仪仗队[SDOI2008]\[LuoguP2158]

欢迎大家访问我的老师的OJ———caioj.cn

题面描述

传送门

思路

这道题和可见点数没有差别。

欧拉函数做法就不写了。

主要讲讲莫反做法吧。

回顾一下Zap(这真的是一道模板题啊!)

D ( a , b , k ) D(a,b,k) D(a,b,k)表示满足 x ≤ a , y ≤ b x\le a,y\le b xa,yb k ∣ gcd ⁡ ( x , y ) k \mid \gcd(x,y) kgcd(x,y)的二元组有多少对。

由于 D ( a , b , k ) = ⌊ a / k ⌋ ∗ ⌊ b / k ⌋ D(a,b,k)=\left\lfloor a/k\right\rfloor* \left\lfloor b/k\right\rfloor D(a,b,k)=a/kb/k

F ( a , b ) F(a,b) F(a,b)表示满足 x ≤ a , y ≤ b x\le a,y\le b xa,yb并且 x , y x,y x,y互质的二元组有多少对。

由于

F ( a , b ) = ∑ i = 1 min ⁡ ( a , b ) μ ( i ) ∗ D ( a , b , i ) F(a,b)=\sum_{i=1}^{\operatorname{min}(a,b)}\mu(i)*D(a,b,i) F(a,b)=i=1min(a,b)μ(i)D(a,b,i)

因为本题要求的是除(1,0),(0,1)两点以外, ∀ x , y ∈ [ 1 , n ] , gcd ⁡ ( x , y ) = 1 \forall x,y\in[1,n],\gcd(x,y)=1 x,y[1,n],gcd(x,y)=1的对数。

F ( n , n ) + 2 F(n,n)+2 F(n,n)+2就为所求。

+ 2 +2 +2是因为 ( 1 , 0 ) , ( 0 , 1 ) (1,0),(0,1) (1,0),(0,1)

AC code

#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int N=4e4+10;
const int M=2e4+10;
int n,m,mu[N],prime[M];bool v[N];
void g_p()
{
	memset(v,false,sizeof(v));m=0;mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!v[i])mu[i]=-1,prime[++m]=i;
		for(int j=1;j<=m&&i*prime[j]<=n;j++)
		{
			v[i*prime[j]]=1;
			if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
			mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=2;i<=n;i++)mu[i]+=mu[i-1];
}
inline ll calc(int a,int b)
{
	if(a>b)swap(a,b);ll ans=0;
	for(int x=1,gx;x<=a;x=gx+1)
	{
		gx=min(a/(a/x),b/(b/x));
		ans+=(ll)(mu[gx]-mu[x-1])*(a/x)*(b/x);
	}
	return ans;
}
int main()
{
	scanf("%d",&n);
	if(n==1){puts("0");return 0;}
	n--;
	g_p();
	ll ans=calc(n,n);
	printf("%lld\n",ans+2);
	return 0;
}

你可能感兴趣的:(莫比乌斯反演,欧拉函数)