您的位置:首页 > 其它

[BZOJ2190][SDOI2008]仪仗队(欧拉函数|莫比乌斯反演)

2017-08-11 23:11 381 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2190

题解:点(x,y)如果gcd(x,y)=1才能被看到

我们把c点看做(0,0),那么我们分离出一个(n−1)∗(n−1)的矩阵,这个矩阵上能看到的点是对称的,所以我们分离出他的上三角形部分,他的第i行(2<=i<=n−1)能被看到的点有φ(i)个

所以ans=∑i=2n−1φ(i)+3,另3个点分别是(1,1),(1,0),(0,1)

另见:http://blog.csdn.net/mosquito_zm/article/details/77102038

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 11;
const int maxp = 1e4 + 10;
int primes[maxp],pcnt;
int phi[maxn];
long long sum[maxn];
void get_phi_and_primes(int n){
for(int i = 1;i <= n;i++) phi[i] = 0;
phi[1] = 1;
for(int i = 2;i <= n;i++){
if(!phi[i]) {
primes[++pcnt] = i;phi[i] = i - 1;
}
for(int j = 1;j <= pcnt && primes[j] * i <= n;j++){
int t = primes[j];
if(i % primes[j] == 0){
phi[i * t] = phi[i] * t;
break;
}
else phi[i * t] = phi[i] * (t - 1);
}
}
}
void getsum(int n){
sum[0] = 0;
for(int i = 1;i <= n;i++)
sum[i] = sum[i - 1] + phi[i];
}
int main()
{
get_phi_and_primes(maxn - 10);
getsum(maxn - 10);
long long n;scanf("%lld",&n);
long long ans = 0;
ans = sum[n - 1] * 2 + 1;
printf("%lld",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm