bzoj3944sum
来源:互联网 发布:淘宝橙色cmyk 编辑:程序博客网 时间:2024/06/06 02:18
传送门
杜教筛
可以知道
把式子转化成
这样的话每个
容斥一下
式子变为
可以看出后面其实是一个规模较小的问题
直接上杜教筛
#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn=2000000+10;typedef long long ll;ll phi[maxn];ll mu[maxn];ll prime[maxn];ll ps=0;ll q[maxn],p[maxn];int vis[maxn];ll m=2000000;ll n;int done[maxn];inline void get_prime(){ mu[1]=1; phi[1]=1; for(int i=2;i<=m;i++){ if(!vis[i]){ prime[++ps]=i; mu[i]=-1; phi[i]=i-1; } for(int j=1;j<=ps;j++){ if(prime[j]*i>m) break; vis[i*prime[j]]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; phi[i*prime[j]]=phi[i]*prime[j]; break; } else { mu[i*prime[j]]=-mu[i]; phi[i*prime[j]]=phi[i]*(prime[j]-1); } } } for(int i=2;i<=m;i++) mu[i]+=mu[i-1],phi[i]+=phi[i-1];}inline ll get_phi(ll x){ if(x<=m) return phi[x]; return q[n/x];}inline ll get_mu(ll x){ if(x<=m) return mu[x]; return p[n/x];}inline void work(ll x){ if(x<=m) return ; //printf("%lld\n",x); ll t=n/x; if(done[t]) return ; done[t]=1; ll nw=2; p[t]=1,q[t]=(x*(x+1ll)/2); while(nw<=x){ ll tmp=x/nw; ll r=x/tmp; work(tmp); p[t]-=get_mu(tmp)*(r-nw+1);q[t]-=get_phi(tmp)*(r-nw+1); nw=r+1; }}int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); ll T; scanf("%lld",&T); get_prime(); while(T--){ scanf("%lld",&n); memset(done,0,sizeof(done)); if(n<=m) printf("%lld %lld\n",phi[n],mu[n]); else { work(n); printf("%lld %lld\n",q[1],p[1]); } }return 0;}
阅读全文
0 0
- bzoj3944sum
- 百度算法更新大全(2013
- Android原生实现 计算器
- 51nod 1348 乘积之和 分治+NTT+中国剩余定理
- Bailian2798 2进制转化为16进制【进制】
- 欢迎使用CSDN-markdown编辑器TEST
- bzoj3944sum
- Python_Geany打印中文报错问题——解决
- 网页打开新窗口——Window.open()详解
- 《七点三刻》044期 春运抢票攻略来了/苹果期货上市/高校开无人机专业/百度怒了
- JAVA设计模式初探之装饰者模式
- 一名3年工作经验的程序员应该具备的技能
- 《算法艺术与信息学竞赛》之 并查集 scau1138 代码等式
- 工作的一个阶段性总结
- Magic Retouch Pro for Mac(Photoshop磨皮润肤插件) v4.0 破解版