一道比较简单的莫比乌斯反演,不过ans会爆long long,我是用结构体来存结果的,结构体中两个LL型变量分别存大于1e17和小于1e17的部分
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=1e6; int prime[maxn+5]; bool check[maxn+5]; int mu[maxn+5]; void init() { mu[1]=1; int tot=0; for(int i=2;i<=maxn;i++) { if(!check[i]) { prime[tot++]=i; mu[i]=-1; } for(int j=0;j<tot;j++) { if(i*prime[j]>maxn) break; check[i*prime[j]]=true; if(i%prime[j]==0) { mu[i*prime[j]]=0; break; } else { mu[i*prime[j]]=-mu[i]; } } } } LL n; const LL mod=1e17; struct node { LL a,b; node(LL a_=0,LL b_=0) { a=a_,b=b_; } void print() { if(a) printf("%lld%017lld\n",a,b); else printf("%lld\n",b); } }; node add(node x,LL y) { if(y>=0) { LL t1=(x.b+y)/mod; LL t2=(x.b+y)%mod; x.a+=t1,x.b=t2; return x; } else { LL t1=(x.b+y)/mod; LL t2=(x.b+y)%mod; if(x.a>0&&t2<0) t2+=mod,t1--; x.a+=t1,x.b=t2; return x; } } int main() { init(); int T; node t; LL x; scanf("%d",&T); while(T--) { scanf("%lld",&n); node ans; for(int i=1;i<=n;i++) ans=add(ans,mu[i]*(n/i)*(n/i)*(n/i)); for(int i=1;i<=n;i++) ans=add(ans,mu[i]*(n/i)*(n/i)*3); ans=add(ans,3); ans.print(); } }
时间: 2024-10-04 08:47:57