BZOJ2190 SDOI2008 仪仗队

这题目一看数学色彩就很浓

通过观察图(这个。。)我们就可以发现,如果按对角线剖分的话,两边可以看到的学生数都恰好是1~n-1范围内的互质数对数,即sigma(phi(i))

phi就是欧拉函数,关于线性求欧拉函数可以点这里:

http://blog.csdn.net/ji414341055/article/details/5771066

那么这题就基本已经解决了,答案就是1~n-1的欧拉函数和*2-1,需要注意的还有两个地方:开unsigned long long和特判n<2的情况

Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define ll long long
#define ull unsigned long long

using namespace std;

bool f[40001];
ull p[40001];
ull ans[40001];

int main(){
	int n,tot=0;
	cin >>n;
	if (n<=1){
		cout <<0 <<endl;
		return 0;
	}
	memset(f,false,sizeof(f));
	f[1]=true;
	for (int i=2;i<=n;i++){
		if (!f[i]){
			p[++tot]=i;
			ans[i]=i-1;
		}
		for (int j=1;(j<=tot)&&(i*p[j]<=n);j++){
			f[i*p[j]]=true;
			if (i%p[j]==0){
					ans[i*p[j]]=ans[i]*p[j];
					break;
			}
			else{
				ans[i*p[j]]=ans[i]*(p[j]-1);
			}
		}
	}
	long long pr=2;
	for (int i=2;i<=n-1;i++) pr+=ans[i];
	cout <<pr*2-1 <<endl;
	return 0;
}

 

你可能感兴趣的:(2008)