您的位置:首页 > 其它

bzoj2818Gcd 莫比乌斯反演

2017-06-09 10:11 417 查看
其实这题可以用欧拉函数做,我只是闲得蛋疼用反演而已。。



最后那一坨分块搞一下就好了

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N=1e7+5;
ll n,ans,p
,pri
,mu
;
int main()
{
int tot=0;
scanf("%lld",&n);
mu[1]=1;
fo(i,2,n)
{
if (!p[i])
{
pri[++tot]=i;
mu[i]=-1;
}
fo(j,1,tot)
{
if (pri[j]*i>n)break;
p[i*pri[j]]=1;
if (i%pri[j]==0)
{
mu[i*pri[j]]==0;
break;
}
else mu[i*pri[j]]=-mu[i];
}
mu[i]+=mu[i-1];
}
for(ll d=1;d<=tot&&pri[d]<=n;++d)
{
ll m=(ll)n/pri[d];
ll j=0;
for(ll i=1;i<=m;i=j+1)
{
j=min(m,m/(m/i));
ans+=(m/i)*(m/i)*(mu[j]-mu[i-1]);
}
}
printf("%lld\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: