P6271 [湖北省隊互測2014]一個人的數論
阿新 • • 發佈:2022-03-14
\(\text{Solution}\)
題目大意是求
\[\sum_{i = 1}^n [i \perp n]i^k \]簡單的推一波柿子
\[=\sum_{i = 1}^n\sum_{d|gcd(i,n)}\mu(d)i^k \] \[=\sum_{d|n}\mu(d)d^k\sum_{i = 1}^{\lfloor\frac{n}{d}\rfloor}i^k \]這不是自然數冪和嗎?拉格朗日插出多項式係數\(a_i\),所以可以換一種表示方式
\[=\sum_{d|n}\mu(d)d^k\sum_{i = 0}^{k+1}a_i(\lfloor\frac{n}{d}\rfloor)^i \] \[=\sum_{i = 0}^{k + 1}a_in^i\sum_{d|n}\mu(d)d^{k-i} \]注意到\(\mu(d)d^k\)
到這就隨便做了
\(\text{Code}\)
#include<cstdio> #define LL long long using namespace std; const int P = 1e9 + 7,N = 1e3 + 5; int k,w; LL p[N],pm[N][105],g[105],S[105],A[105]; LL fpow(LL x,LL y) { LL res = 1; for (; x; x >>= 1,y = y * y % P) if (x & 1) res = res * y % P; return res; } int main() { scanf("%d%d",&k,&w); LL n = 1; for (int i = 1,q; i <= w; i++) scanf("%lld%d",&p[i],&q),pm[i][1] = 1,pm[i][0] = fpow(P - 2,p[i]),n = n * fpow(q,p[i]) % P; for (int i = 1; i <= w; i++) for (int j = 2; j <= k + 1; j++) pm[i][j] = (LL)pm[i][j - 1] * p[i] % P; for (int i = 1; i <= k + 2; i++) g[i] = (g[i - 1] + fpow(k,i)) % P; S[0] = P - 1,S[1] = 1; for (int i = 2; i <= k + 2; i++) { for (int j = i; j >= 1; j--) S[j] = (S[j - 1] - (LL)S[j] * i % P + P) % P; S[0] = (P - S[0] * i % P) % P; } for (int i = 1; i <= k + 2; i++) { LL C = 1,sc = S[k + 2]; for (int j = 1; j <= k + 2; j++) if (i != j) C = C * (i - j + P) % P; C = g[i] * fpow(P - 2,C) % P; for (int j = k + 1; j >= 0; j--) A[j] = (A[j] + C * sc % P) % P,sc = (S[j] + sc * i % P + P) % P; } LL ans = 0,sn = 1; for (int i = 0; i <= k + 1; i++) { LL res = 1; for (int j = 1; j <= w; j++) res = res * (P + 1 - pm[j][k - i + 1]) % P; ans = (ans + A[i] * sn % P * res % P) % P,sn = sn * n % P; } printf("%lld\n",ans); }