P2158 [SDOI2008]仪仗队 - 欧拉函数

如果你以(1,1)为坐标原点,那么是没有什么规律的
但如果你以(0,0)为坐标原点,仔细观察一下能发现每个能看到的点的坐标(x, y)互质
然后(x, y)既然可以那么(y, x)也行
矩阵坐标从0到N-1
注意phi[1] = 1
答案是\(1 + 2 * \sum_{i=1}^{N-1} \phi(i)\)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 100000 + 10;
const int INF = 1 << 30;
typedef long long ll;
ll n,ans;  
ll prime[MAXN],phi[MAXN],vis[MAXN],tot;
void primes(int n) {
	phi[1] = 1;
	for(int i=2; i<=n; i++) {
		if(!vis[i]) {
			phi[i] = i-1;
			prime[++tot] = i;
		}
		for(int j=1; j<=tot && i*prime[j] <= n; j++) {	
			vis[i*prime[j]] = 1;
			if(i % prime[j] == 0) {
				phi[i*prime[j]] = phi[i] * prime[j];
				break;
			}
			phi[i*prime[j]] = phi[i] * (prime[j] - 1);
		}
	}
}
int main() {
	scanf("%lld", &n);
	primes(n);
	for(int i=1; i<n; i++) {
		ans += phi[i];
  	}
  	ans = ans * 2 + 1;
  	if(n == 1) ans = 0;
	printf("%lld\n", ans);
	return 0;
}
posted @ 2018-10-30 18:19  Zolrk  阅读(101)  评论(0编辑  收藏  举报