洛谷P4213 【模板】杜教筛(Sum)(杜教筛,莫比乌斯反演)

传送门

坑着,联赛活着回来再填(死了就不填了)

 1 // luogu-judger-enable-o2
 2 //minamoto
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<map>
 6 #define ll long long
 7 using namespace std;
 8 const int N=1e5+5,M=4e6+5,limit=3414680;
 9 map<ll,ll> _mu;
10 map<ll,ll>::iterator ii;
11 ll p[M],m,mu[M];int vis[M];
12 void init(){
13     mu[1]=1;
14     for(ll i=2;i<limit;++i){
15         if(!vis[i]) p[++m]=i,mu[i]=-1;
16         for(int j=1;j<=m&&i*p[j]<limit;++j){
17             vis[i*p[j]]=1;
18             if(i%p[j]==0){
19                 mu[i*p[j]]=0;
20                 break;
21             }
22             mu[i*p[j]]=-mu[i];
23         }
24     }
25     for(int i=1;i<limit;++i)
26     mu[i]+=mu[i-1];
27 }
28 ll sum2(ll n){
29     if(n<limit) return mu[n];
30     if(_mu.count(n)) return _mu[n];
31     ll ans=1;
32     for(int i=2,r;i<=n;i=r+1){
33         r=n/(n/i);
34         ans-=(r-i+1)*sum2(n/i);
35     }
36     return _mu[n]=ans;
37 }
38 ll sum1(ll n){
39     ll ans=0;
40     for(ll i=1,r;i<=n;i=r+1){
41         r=n/(n/i);
42         ans+=(n/i)*(n/i)*(sum2(r)-sum2(i-1));
43     }
44     return ((ans-1)>>1)+1;
45 }
46 int main(){
47 //    freopen("testdata.in","r",stdin);
48     init();
49     ll T,n;scanf("%lld",&T);
50     while(T--){
51         scanf("%lld",&n);
52         printf("%lld %lld\n",sum1(n),sum2(n));
53     }
54     return 0;
55 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9688051.html