杜教筛模版

 1 #include<bits/stdc++.h>
 2 #include<ext/pb_ds/assoc_container.hpp>
 3 using namespace __gnu_pbds;
 4 using namespace std;
 5 int n,m,T,ans;
 6 const int MAXN=7000000;
 7 vector<int>prime;
 8 bool check[MAXN+5];
 9 short mob[MAXN+5],premob[MAXN+5];
10 int phi[MAXN+5];
11 long long prephi[MAXN+5];
12 void sieve()
13 {
14     prephi[1]=phi[1]=1;         //欧拉筛
15     premob[1]=mob[1]=1;         //莫比乌斯函数筛
16     for(int i=2;i<=MAXN;i++)
17     {
18         if(check[i]==0)
19         {
20             prime.push_back(i);
21             phi[i]=i-1;
22             mob[i]=-1;
23         }
24         for(int j=0;j<prime.size()&&i*prime[j]<=MAXN;j++)
25         {
26             check[i*prime[j]]=1;
27             if(i%prime[j]==0)
28             {
29                 phi[i*prime[j]]=phi[i]*prime[j];
30                 mob[i*prime[j]]=0;
31                 break;
32             }
33             phi[i*prime[j]]=phi[i]*(prime[j]-1);
34             mob[i*prime[j]]=-mob[i];
35         }
36         prephi[i]=prephi[i-1]+phi[i];
37         premob[i]=premob[i-1]+mob[i];
38     }
39 }
40 struct DuSieve
41 {
42     function<long long(int)>get_preFcovG,get_preG,get_preF;
43     gp_hash_table<int,long long>F;
44     long long get_preF(int n)
45     {
46         if(n<=MAXN)return get_preF(n);
47         if(F.find(n)!=F.end())return F[n];
48         long long ans=get_preFcovG(n);
49         for(long long l=2,r;l<=n;l=r+1)
50         {
51             r=n/(n/l);
52             ans-=(get_preG(r)-get_preG(l-1))*get_preF(n/l);
53         }
54         return F[n]=ans;
55     }
56     DuSieve(function<long long(int)>FcG,function<long long(int)>pG,function<long long(int)>pF)
57     {
58         get_preFcovG=FcG;
59         get_preG=pG;
60         get_preF=pF;
61     }
62 };
63 int main()
64 {
65     sieve();
66     DuSieve PHI=DuSieve([](int n) {return (1ll+n)*n/2;},[](int n) {return n;},[](int n) {return prephi[n];});
67     DuSieve MU=DuSieve([](int n) {return 1;},[](int n) {return n;},[](int n) {return premob[n];});
68     scanf("%d",&T);
69     while(T--)
70     {
71         scanf("%d",&n);
72         printf("%lld %lld\n",PHI.get_preF(n),MU.get_preF(n));
73     }
74     return 0;
75 }

猜你喜欢

转载自www.cnblogs.com/megalovania/p/12513368.html