how to run faster
题目大意:
已知 $$ b_i = \sum_{j=1}^n {(i,j)^d [i,j]^c x_j}$$,给定 $b_i$ 求解 $x_i$
解法:
考虑 $f(n) = \sum_{d|n}{fr(d)}$,这样有 $$\sum_{t|i}{fr(t) \sum_{t|j}{j^d x_j} } = b_i$$
容斥得 $fr(i) \sum_{i|j}{j^d x_j}$ 其中 $fr(n)$ 可以容斥得到,再次容斥得到 $x_i$
注意在除以 $fr(i)$ 时会产生无解,多解的情况。
#include <bits/stdc++.h> #define LL long long #define LD double #define FOR(i,a,b) for (int i = (a);i <= (b); i++) #define DFOR(i,a,b) for (int i = (a);i >= (b); i--) #define debug(x) cerr << "debug: " << (#x) << " = " << (x) <<endl; #define PI acos(-1) #define mp make_pair #define pb push_back #define itr iterator #define bit(x) (1LL<<(x)) #define lb(x) ((x)&(-x)) #define sqr(x) ((x)*(x)) #define gn 3 #define l(x) ch[x][0] #define r(x) ch[x][1] #define y0 Y0 #define y1 Y1 #define y2 Y2 #define fir first #define sec second using namespace std; const int N = 300010; const LL P = 998244353ll; LL Cc,Dd,fr[N],z[N]; LL qpow(LL x,int n) { LL ans=1; for(;n;n>>=1,x=x*x%P) if(n&1) ans=ans*x%P; return ans; } int main() { int n,q; cin >> n >> Cc >> Dd >> q; FOR(i,1,n) fr[i] = qpow(i,(Cc-Dd+P-1)%(P-1)); FOR(i,1,n) for(int j=i+i;j<=n;j+=i) fr[j] = (fr[j]+P-fr[i])%P; while(q--) { FOR(i,1,n) { scanf("%lld",&z[i]); z[i] = z[i] * qpow(qpow(i,Dd), P-2)%P; } FOR(i,1,n) for(int j=i+i;j<=n;j+=i) z[j] = (z[j]+P-z[i])%P; bool nosol = 0,mulsol = 0; FOR(i,1,n) { if(fr[i]==0 && z[i]!=0) nosol = 1; else if(fr[i]==0 && z[i]==0) mulsol = 1; z[i] = z[i] * qpow(fr[i],P-2)%P; } DFOR(i,n,1) for(int j=i+i;j<=n;j+=i) z[i] = (z[i]+P-z[j])%P; if(nosol) puts("-1"); else { FOR(i,1,n) z[i] = z[i] * qpow(qpow(i,Dd),P-2)%P; FOR(i,1,n) printf("%lld ",z[i]); printf("\n"); } } return 0; }