杜教筛模板

Posted guapisolo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杜教筛模板相关的知识,希望对你有一定的参考价值。

题目大意:略

卡常终于卡过了!!!!卡常真的蛋疼

  1 // luogu-judger-enable-o2
  2 #pragma GCC optimize(2)
  3 #pragma GCC optimize(3)
  4 #pragma GCC optimize"Ofast"
  5 #include <cstdio>
  6 #include <cstring>
  7 #include <algorithm>
  8 #define NN 3001000
  9 #define MM 3000100
 10 #define maxn 3000000
 11 #define ll long long 
 12 #define uint unsigned int
 13 #define mod 1000000007
 14 using namespace std;
 15 
 16 int N,K,l,r,sq,len;
 17 namespace S1{
 18 int pr[NN],use[NN],mu[NN],phi[NN],smu[NN],cnt;
 19 ll sphi[NN];
 20 void Pre()
 21 {
 22     mu[1]=smu[1]=1,phi[1]=sphi[1]=1;
 23     for(int i=2;i<=maxn;i++)
 24     {
 25         if(!use[i]) pr[++cnt]=i,mu[i]=-1,phi[i]=i-1;
 26         smu[i]=smu[i-1]+mu[i],sphi[i]=sphi[i-1]+phi[i];
 27         for(int j=1;j<=cnt&&i*pr[j]<=maxn;j++){
 28             use[i*pr[j]]=1;
 29             if(i%pr[j]==0){
 30                 mu[i*pr[j]]=0;
 31                 phi[i*pr[j]]=phi[i]*pr[j];
 32                 break;
 33             }else{
 34                 mu[i*pr[j]]=-mu[i];
 35                 phi[i*pr[j]]=phi[i]*phi[pr[j]];
 36             }
 37         }
 38     }
 39 }
 40 };
 41 struct Chain{
 42     #define maxx 3000000
 43     int nxt[MM],head[MM],to[MM],cte;
 44     ll val[MM];
 45     void ae(int u,int v,ll w){
 46         cte++;to[cte]=v,val[cte]=w;
 47         nxt[cte]=head[u],head[u]=cte;
 48     }
 49     ll find(int U){
 50         int u=U%maxx;
 51         for(int j=head[u];j;j=nxt[j]){
 52             ll v=to[j];
 53             if(v==U) return val[j];
 54         }return -1;
 55     }
 56     void ins(int U,ll w){
 57         int u=U%maxx;
 58         ae(u,U,w);
 59     }
 60     #undef maxx
 61 }mu,phi;
 62 ll query_mu(int n)
 63 {
 64     if(n<=maxn) return S1::smu[n];
 65     ll ans;
 66     ans=mu.find(n);
 67     if(ans!=-1) return ans;
 68     ans=1;
 69     for(int i=2,la;i<=n;i=la+1){
 70         la=n/(n/i);
 71         ans-=1ll*(la-i+1)*query_mu(n/i);
 72     }mu.ins(n,ans);
 73     return ans;
 74 }
 75 ll query_phi(int n)
 76 {
 77     if(n<=maxn) return S1::sphi[n];
 78     ll ans;
 79     ans=phi.find(n);
 80     if(ans!=-1) return ans;
 81     ans=1ll*n*(n+1)/2;
 82     for(int i=2,la;i<=n;i=la+1){
 83         la=1ll*n/(n/i);
 84         ans-=1ll*(la-i+1)*query_phi(n/i);
 85     }phi.ins(n,ans);
 86     return ans;
 87 }
 88 
 89 int main()
 90 {
 91     //freopen("t1.in","r",stdin);
 92     int T;ll n;
 93     S1::Pre();
 94     scanf("%d",&T);
 95     while(T--){
 96         scanf("%lld",&n);
 97         ll ans_mu=query_mu(n);
 98         ll ans_phi=query_phi(n);
 99         printf("%lld %lld
",ans_phi,ans_mu);
100     }
101     return 0;
102 }

 

以上是关于杜教筛模板的主要内容,如果未能解决你的问题,请参考以下文章

模板杜教筛(Sum)

模板 - 杜教筛

杜教筛模板

杜教筛模板

模板杜教筛(Sum)

模板杜教筛