[NOI2010]能量采集
ans=2*(Σ(1<=i<=n)Σ(1<=j<=m)GCD(i,j))-m*n,
经典的反演。
#include<bits/stdc++.h> #define N 100007 #define LL long long LL ans,sum[N],p[N>>2],u[N],tot; using namespace std; void get() { sum[1]=1; for (int i=2;i<N;i++) { if(!u[i]) p[++tot]=i,u[i]=i-1; for (int j=1;j<=tot&&i*p[j]<N;j++) if (i%p[j]) u[i*p[j]]=u[i]*(p[j]-1); else {u[i*p[j]]=u[i]*p[j];break;} sum[i]=sum[i-1]+u[i]; } } int n,m,k; int main () { scanf("%d%d",&n,&m); get(); k=min(n,m); for (int i=1,last;i<=k;i=last+1){ last=min(n/(n/i),m/(m/i)); ans+=(sum[last]-sum[i-1])*(n/i)*(m/i); } printf("%lld\n",ans*2-(LL)n*m); }