BZOJ 2005: [Noi2010]能量採集(容斥+數論)
阿新 • • 發佈:2018-12-10
解題思路
首先題目要求的其實就是\(\sum\limits_{i=1}^n \sum\limits_{j=1}^m [(gcd(i,j)-1)*2+1)]\),然後變形可得\(-n*m+2\sum\limits_{i=1}^n \sum\limits_{j=1}^m gcd(i,j)\)。所以本質上是求後面那個式子,設\(f[i]\)表示\(i\)這個約數作為\(gcd\)的次數,然後轉移時考慮容斥,\(n/i*m/i\)表示含有\(i\)這個約數的數字個數,再減去\(f[i*2],f[i*3]...\)這些\(gcd\)不為\(i\)的。
程式碼
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 100005; typedef long long LL; LL f[MAXN],ans; int n,m; int main(){ scanf("%d%d",&n,&m);if(n>m) swap(n,m); for(int i=n;i;i--){ f[i]=(LL)(n/i)*(m/i); for(int j=(i<<1);j<=n;j+=i) f[i]-=f[j]; ans+=f[i]*i; } printf("%lld",ans*2-(LL)n*m); return 0; }