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

来源:互联网 发布:f1 2015知乎 编辑:程序博客网 时间:2024/06/15 07:04

题目链接: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;}


原创粉丝点击