File tree Expand file tree Collapse file tree 1 file changed +60
-1
lines changed
Expand file tree Collapse file tree 1 file changed +60
-1
lines changed Original file line number Diff line number Diff line change @@ -82,4 +82,63 @@ int main() {
8282 }
8383}
8484
85- ```
85+ ```
86+
87+ ## 別解
88+ [ ユーザー解説] ( https://atcoder.jp/contests/abc349/editorial/9794 ) 通りにやってみる。
89+ $ Z^{-1}(Z(X)\cdot Z(Y))_ n= \sum _ {\mathrm{lcm}(i,j)=n}X_i Y_j $ が重要。$(Z(X_1)\cdot Z(X_2)\cdot\dots \cdot Z(X_N))_ n = 2^{c_n} $となる$c_n$をゼータ変換で求めて左辺の列をメビウス変換する。
90+ ``` cpp
91+ #include " /home/y_midori/cp/library/template.hpp"
92+ #include " data_structure/hash-map-variable-length.hpp"
93+ #include " math/pollard_rho.hpp"
94+ #include < atcoder/modint>
95+ using mint = atcoder::modint998244353;
96+ void solve () {
97+ LL (n, m);
98+ vl d = divisors(m);
99+ HashMap<ll > c;
100+ rep(i, n) {
101+ LL(a);
102+ if(m % a)
103+ continue;
104+ c[ a] ++;
105+ }
106+ auto fc = factor_count(m);
107+ // ゼータ変換
108+ for(auto [ p, e] : fc) {
109+ rep(i, d.size()) {
110+ if(d[ i] % p == 0) {
111+ c[ d[ i]] += c[ d[ i] / p] ;
112+ }
113+ }
114+ }
115+ HashMap<mint > x;
116+ rep(i, d.size()) {
117+ x[ d[ i]] = mint(2).pow(c[ d[ i]] );
118+ }
119+
120+ // メビウス変換
121+ for(auto [p, e] : factor_count(m)) {
122+ for(int i = ssize(d) - 1; i >= 0; i--) {
123+ if(d[i] % p == 0) {
124+ x[d[i]] -= x[d[i] / p];
125+ }
126+ }
127+ }
128+ auto ans = x[m];
129+ if(m == 1)
130+ ans--;
131+ cout << ans.val() << endl;
132+ }
133+
134+ int main () {
135+ ios::sync_with_stdio (false);
136+ std::cin.tie(nullptr);
137+ cout << std::setprecision(16);
138+ int t = 1;
139+ rep(_ , t) {
140+ solve();
141+ }
142+ }
143+
144+ ```
You can’t perform that action at this time.
0 commit comments