spoj GCDEX【线性筛】

来源:互联网 发布:ddos攻击阿里云事件 编辑:程序博客网 时间:2024/05/27 20:03

由于这里f(n)是两个积性函数的卷积,它也是积性的,可以用线性筛预处理出来,而答案即为


时间复杂度O(N+T)

#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;typedef long long LL;inline int read(){int x=0;bool f=0;char c=getchar();for (;c<'0'||c>'9';c=getchar()) f=c=='-'?1:0;for (;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';return f?-x:x;}const int N=1000000,M=N+10;int n,pr[M],pc=0,p[M],a[M],pa[M],g[M],f[M];LL sum[N];int main(){for (int i=2;i<=N;i++){if (!p[i]) pr[++pc]=p[i]=pa[i]=i,a[i]=1,g[i]=f[i]=2*i-1;for (int j=1,k=i<<1;j<=pc&&k<=N;k=i*pr[++j]){p[k]=pr[j];if (i%pr[j]==0){f[k]=f[i]/g[i];g[k]=(a[i]+2)*pa[i]*p[i]-(a[i]+1)*pa[i];a[k]=a[i]+1;pa[k]=pa[i]*p[i];f[k]*=g[k];break;}g[k]=g[pr[j]];f[k]=f[i]*g[pr[j]];a[k]=1;pa[k]=pr[j];}}for (int i=2;i<=N;i++) sum[i]=sum[i-1]+f[i]-i;while (scanf("%d",&n)!=EOF&&n) printf("%lld\n",sum[n]);return 0;}


0 0
原创粉丝点击