BZOJ 3944 Sum
题解:
杜教筛
坑点 n+1会炸int
注意空间
到现在不会unsigned long long的输出
//注意空间 //注意读入数据2^31-1 //unsighed long long 输出 #include<iostream> #include<cstdio> #include<cstring> #include<map> using namespace std; typedef long long Lint; typedef unsigned long long uLint; const int u=5000000; int TT; int q[10000]; uLint ans1[100000]; int ans2[100000]; map<int,uLint>ma1; map<int,int>ma2; int vis[u+10]={0}; int cntprime=0,prime[u+10]; Lint mu[u+10]; Lint phi[u+10]; void Lineshake(){ vis[1]=1;mu[1]=1;phi[1]=1; for(int i=2;i<=u;++i){ if(!vis[i]){ prime[++cntprime]=i; mu[i]=-1; phi[i]=i-1; } for(int j=1;(j<=cntprime)&&(i*prime[j]<=u);++j){ vis[i*prime[j]]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; phi[i*prime[j]]=phi[i]*prime[j]; break; } mu[i*prime[j]]=-mu[i]; phi[i*prime[j]]=phi[i]*(prime[j]-1); } } for(int i=2;i<=u;++i){ mu[i]+=mu[i-1]; phi[i]+=phi[i-1]; } } uLint Calphi(int n){ if(n<=u)return phi[n]; if(ma1.count(n))return ma1[n]; uLint ret=((uLint)n)*((uLint)n+1)/2; Lint last; for(Lint d=2;d<=n;d=last+1){ last=n/(n/d); ret-=(last-d+1)*Calphi(n/d); } ma1[n]=ret; return ret; } int Calmu(int n){ if(n<=u)return mu[n]; if(ma2.count(n))return ma2[n]; int ret=1; Lint last; for(Lint d=2;d<=n;d=last+1){ last=n/(n/d); ret-=(last-d+1)*Calmu(n/d); } ma2[n]=ret; return ret; } int main(){ Lineshake(); scanf("%d",&TT); for(int i=1;i<=TT;++i)scanf("%d",&q[i]); for(int i=1;i<=TT;++i){ ans1[i]=Calphi(q[i]); } for(int i=1;i<=TT;++i){ ans2[i]=Calmu(q[i]); } for(int i=1;i<=TT;++i){ cout<<ans1[i]<<' '<<ans2[i]<<endl; } return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!