谎言重复|

Day_Dreamer_D

园龄:3年6个月粉丝:3关注:16

2022-10-12 12:03阅读: 121评论: 0推荐: 0

洛谷 P2158 [SDOI2008] 仪仗队 题解

来一发莫比乌斯反演的题解。

ans=i=1n1j=1n1[gcd(i,j)=1]=i=1n1j=1n1d|gcd(i,j)μ(d)=d=1nμ(d)i=1n1dj=1n1d=d=1nμ(d)×(n1d)2

n1g 可以用数论分块求出。

//P2158 [SDOI2008] 仪仗队
#include <cstdio>
#include <cstdlib>
using namespace std;
const int MAXN=40005;
int prime[MAXN],cnt,mu[MAXN],s[MAXN],n,ans;
bool flag[MAXN];
void sieve()
{
mu[1]=1;
for(int i=2;i<=4e4;i++)
{
if(!flag[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=4e4;j++)
{
flag[i*prime[j]]=true;
if(i%prime[j]==0)
{
break;
}
mu[i*prime[j]]=-mu[i];
}
}
return;
}
int main()
{
sieve();
scanf("%d",&n);
if(!--n)
{
printf("0\n");
exit(0);
}
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+mu[i];
}
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
ans+=(s[r]-s[l-1])*(n/l)*(n/r);
}
printf("%d\n",ans+2);
return 0;
}
/*
* 洛谷
* https://www.luogu.com.cn/problem/P2158
* C++17 -O0
* 2022.10.12
*/

本文作者:Day_Dreamer_D's Blog

本文链接:https://www.cnblogs.com/2020gyk080/p/16784088.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Day_Dreamer_D  阅读(121)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起