step4 自己寫一遍Min_25篩,并做相關的習題 這里采用一道例題,BZOJ3944 Sum 這道題其實也是杜教篩模板題,這里用Min_25篩的板子也不錯 貼出代碼
#include<cstdio>#include<cctype>#include<cstring>#include<algorithm>#include<cmath>
namespace fast_IO
{constint IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inlinechargetchar_(){return(ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inlinevoidputchar_(constchar x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inlinevoidflush(){fwrite(obuf,1,oh-obuf,stdout);}}
using namespace fast_IO;#define getchar() getchar_()#define putchar(x) putchar_((x))#define rg registertypedeflonglong LL;
template <typename T>inline T max(const T a,const T b){return a>b?a:b;}
template <typename T>inline T min(const T a,const T b){return a<b?a:b;}
template <typename T>inlinevoidmind(T&a,const T b){a=a<b?a:b;}
template <typename T>inlinevoidmaxd(T&a,const T b){a=a>b?a:b;}
template <typename T>inline T abs(const T a){return a>0?a:-a;}
template <typename T>inlinevoidswap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T>inline T gcd(const T a,const T b){if(!b)return a;returngcd(b,a%b);}
template <typename T>inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T>inline T square(const T x){return x*x;};
template <typename T>inlinevoidread(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;}
template <typename T>inlinevoidprinte(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');}
template <typename T>inlinevoidprint(const T x){if(x<0)putchar('-'),printe(-x);elseprinte(x);}
LL sum1[700001];int T,n,part,tot,qz[700001],prime[700001],sq[700001],primesize,sum0[700001],id[700001];inlineintck(constint x){return x<=part?x:tot-n/x+1;}intcalc_mu(constint a,constint b){if(a<prime[b])return0;int ans=sum0[ck(a)]+b-1;for(rg int i=b;i<=primesize&&sq[i]<=a;i++)ans-=calc_mu(a/prime[i],i+1);return ans;}
LL calc_phi(constint a,constint b){if(a<prime[b])return0;LL ans=sum1[ck(a)]-(qz[b-1]-(b-1));for(rg int i=b;i<=primesize&&sq[i]<=a;i++){ans+=(calc_phi(a/prime[i], i+1)+prime[i])*(prime[i]-1);for(rg int x=prime[i]*prime[i],mine=x-prime[i];(LL)x*prime[i]<=a;x*=prime[i],mine*=prime[i])ans+=(calc_phi(a/x, i+1)+prime[i])*mine;}return ans;}intmain(){read(T);while(T--){read(n);if(!n){print(0),putchar(' '),print(0),putchar('\n');continue;}part=sqrt(n);tot=primesize=0;for(rg int i=1;i<=part;i++)id[++tot]=i,sum0[tot]=i-1,sum1[tot]=((((LL)i+1)*i)>>1)-1;id[++tot]=n/part;if(id[tot]!=part)sum0[tot]=id[tot]-1,sum1[tot]=((LL)(((LL)id[tot]+1)*id[tot])>>1)-1;else tot--;for(rg int i=part-1;i>=1;i--)id[++tot]=n/i,sum0[tot]=id[tot]-1,sum1[tot]=((((LL)id[tot]+1)*id[tot])>>1)-1;for(rg int i=2;i<=part;i++)if(sum0[i]!=sum0[i-1]){constint limit=(LL)i*i;for(rg int j=tot;id[j]>=limit;j--){constint t=ck(id[j]/i);sum1[j]-=(sum1[t]-qz[primesize])*i;sum0[j]-=sum0[t]-primesize;}prime[++primesize]=i,sq[primesize]=i*i,qz[primesize]=qz[primesize-1]+i;}for(rg int i=1;i<=tot;i++)sum1[i]-=sum0[i],sum0[i]=-sum0[i];//sum1為phi的前綴和,sum0為mu的前綴和print(calc_phi(n,1)+1),putchar(' '),print(calc_mu(n,1)+1),putchar('\n');}returnflush(),0;}