标签:scanf turn class output ons lld data- int math
有一天,TIBBAR和LXL比赛谁先算出1~N这N个数中每任意两个不同的数的最大公约数的和。LXL还在敲一个复杂而冗长的程序,争取能在100s内出解。而TIBBAR则直接想1s秒过而获得完胜,请你帮他完成这个任务。
共一行,一个正整数N。
共一行,一个数,为1~N这N个数中每任意两个不同的数的最大公约数的和。
10
67
对于40%的数据,2≤N≤2000.
对于100%的数据,2≤N≤2000000.
设f[d]=∑∑gcd(i,j)=d
F[d]=∑∑d|gcd(i,j)
不难看出F[d]=n/d*(n/d)
那么f[d]=F[d]-∑f[kd]
所以o(nlogn)扫一下就好了(主要是代码特别短)
然后ans=(∑f[d]-n*(n+1)/2)/2 减去gcd(d,d)=d的和gcd(i,j)=gcd(j,i)重复的
源自作者: Kelin
代码
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=2000010; long long n,ans,f[N]; int main() { scanf("%lld",&n); for(long long i=n; i>0; i--) {//注意分母不为0!!! f[i]=n/i*(n/i); for(long long j=i<<1; j<=n; j+=i) f[i]-=f[j]; ans+=f[i]*i; } printf("%lld\n",(ans-n*(n+1)/2)/2); return 0; }
标签:scanf turn class output ons lld data- int math
原文地址:https://www.cnblogs.com/mysh/p/11779196.html