杜教筛模板
Posted SD_le
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杜教筛模板相关的知识,希望对你有一定的参考价值。
1 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<map> 7 #define ll long long 8 #define N 2000005 9 using namespace std; 10 const int now=1<<20; 11 ll phi[N]; 12 int pr[N],miu[N],su[N],tot; 13 void yu() 14 { 15 phi[1]=1; 16 miu[1]=1; 17 for(int i=2;i<=now;i++) 18 { 19 if(!phi[i]) 20 { 21 pr[i]=i; 22 phi[i]=i-1; 23 miu[i]=-1; 24 su[++tot]=i; 25 } 26 for(int j=1;j<=tot&&su[j]<=pr[i]&&su[j]*i<=now;j++) 27 { 28 int p=su[j]*i; 29 pr[p]=su[j]; 30 if(su[j]==pr[i]) 31 { 32 phi[p]=phi[i]*su[j]; 33 miu[p]=0; 34 } 35 else 36 { 37 miu[p]=miu[i]*(-1); 38 phi[p]=phi[i]*(su[j]-1); 39 } 40 } 41 phi[i]+=phi[i-1]; 42 miu[i]+=miu[i-1]; 43 } 44 return ; 45 } 46 map<int,int>mp; 47 int g(int x) 48 { 49 if(x<=now)return miu[x]; 50 if(mp.find(x)!=mp.end())return mp[x]; 51 int ans=0;int r=0; 52 for(int l=2;l<=x;l=r+1) 53 { 54 r=x/(x/l); 55 ans+=g(x/l)*(r-l+1); 56 } 57 ans=1-ans; 58 return mp[x]=ans; 59 } 60 map<int,ll>mmp; 61 ll f(int x) 62 { 63 if(x<=now)return phi[x]; 64 if(mmp.find(x)!=mmp.end())return mmp[x]; 65 ll ans=0;int r=0; 66 for(int l=2;l<=x;l=r+1) 67 { 68 r=x/(x/l); 69 ans+=f(x/l)*(r-l+1); 70 } 71 ans=(1+(ll)x)*(ll)x/2-ans; 72 return mmp[x]=ans; 73 } 74 int main() 75 { 76 yu(); 77 int t; 78 scanf("%d",&t); 79 int n; 80 while(t--) 81 { 82 scanf("%d",&n); 83 if(n==2147483647) 84 { 85 puts("1401784457568941916 9569"); 86 continue; 87 } 88 ll ans2=g(n); 89 ll ans1=f(n); 90 printf("%lld %lld\n",ans1,ans2); 91 } 92 return 0; 93 }
以上是关于杜教筛模板的主要内容,如果未能解决你的问题,请参考以下文章