luoguP4213 【模板】杜教筛(Sum)杜教筛
生活随笔
收集整理的這篇文章主要介紹了
luoguP4213 【模板】杜教筛(Sum)杜教筛
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
鏈接
luogu
思路
為了做hdu來(lái)學(xué)杜教篩。
杜教篩模板題。
卡常數(shù),我加了register居然跑到不到800ms。
太深了。
代碼
// luogu-judger-enable-o2 #include <bits/stdc++.h> #define ll long long using namespace std; const int _=5000030; int vis[_],pri[_],cnt,N,limit,mu[_]; ll phi[_]; unordered_map<int,ll> ans_phi; unordered_map<int,ll> ans_mu; inline void Euler() {vis[1]=phi[1]=mu[1]=1;for(register int i=1;i<=limit;++i) {if(!vis[i]) pri[++cnt]=i,mu[i]=-1,phi[i]=i-1;for(register int j=1;j<=cnt&&i*pri[j]<=limit;++j) {vis[i*pri[j]]=1;if(i%pri[j]==0) {mu[i*pri[j]]=0;phi[i*pri[j]]=phi[i]*pri[j];break;} else {mu[i*pri[j]]=-mu[i];phi[i*pri[j]]=phi[i]*(pri[j]-1);}}}for(register int i=2;i<=limit;++i) mu[i]+=mu[i-1],phi[i]+=phi[i-1]; } ll Solvephi(register int n) {if(n<=limit) return phi[n];if(ans_phi[n]) return ans_phi[n];register ll tmp=1LL*n*(n+1)/2;for(register int l=2,r;l<=n;l=r+1)r=n/(n/l),tmp-=Solvephi(n/l)*(r-l+1);return ans_phi[n]=tmp; } ll Solvemu(register int n) {if(n<=limit) return mu[n]; if(ans_mu[n]) return ans_mu[n];register ll tmp=1;for(register int l=2,r;l<=n;l=r+1)r=n/(n/l),tmp-=Solvemu(n/l)*(r-l+1);return ans_mu[n]=tmp; } int main() {int T;cin>>T;limit=5000000;Euler();while(T --> 0) {cin>>N;printf("%lld %lld\n",Solvephi(N),Solvemu(N));}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/dsrdsr/p/11409535.html
總結(jié)
以上是生活随笔為你收集整理的luoguP4213 【模板】杜教筛(Sum)杜教筛的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2019CCPC网络预选赛 八道签到题题
- 下一篇: cf1208G Polygons 欧拉函