3rd 2022/5/9 题目总结·数论篇·欧拉函数·【SDOI2008】仪仗队

3rd 2022/5/9 题目总结·数论篇·欧拉函数·【SDOI2008】仪仗队

原题

作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N 的方阵,为了保证队伍在行进中整齐划一,C 君会跟在仪仗队的生后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。
现在,C 君希望你告诉他队伍整齐时能看到的学生人数。

​ 1<=n<=40000

  img

概要

依图

思路

依图发现:能被看到的点(a,b),中,\(\gcd(a-1,b-1)=1\)

所以,要求的便是1至n-1中,互质的数对数+3(图中上和右两个,并不满足该规律,因为a和b分别为1,而不选右上点是方便计数,因为会重复)

\(O(n^2)\)不可行,考虑欧拉函数的意义,发现就是\(3+2*\sum_{i=1}^{n}\varphi(i)\)

欧拉函数用欧拉筛\(O(n)\)

实现部分

#include<cstdio>
using namespace std;
int n,ans;
int prime[40001],len,bz[40001],f[40001];
int main(){
	scanf("%d",&n);
	for(int i=2;i<=40000;i++){
		if(bz[i]==0){
			prime[++len]=i;
			f[i]=i-1;
		}
		for(int j=1;j<=len&&prime[j]*i<=40000;j++){
			bz[prime[j]*i]=1;
			if(i%prime[j]==0){
				f[prime[j]*i]=f[i]*prime[j];
				break;
			}
			else{
				f[prime[j]*i]=f[i]*(prime[j]-1);
			}
		}
	}
	for(int i=1;i<n;i++){
		ans+=f[i];
	}
	ans*=2;
	ans+=3;
	printf("%d",ans);
}

posted @ 2022-09-23 19:10  Far_delivery  阅读(52)  评论(0)    收藏  举报