您的位置:首页 > 其它

BZOJ2190 [SDOI2008]仪仗队(欧拉函数)

2016-02-05 22:21 489 查看
HDU2841大同小异。

设左下角的点为(1,1),如果(1,1)->(x,y)和(1,1)->(x',y')向量平行,那只有在前面的能被看见。然后就是求x-1、y-1不互质的数对个数。

而x或y等于1可以另外讨论一下,就是当n不等于1时就有两个,n等于1就特判一下。

那么就用欧拉函数计数了:枚举x-1,累加小于x-1与x-1互质的个数,即合法的y-1的个数;结果还要*2,因为还有一半对称的y-1>x-1的情况;此外x-1=y-1多算了一次,减去1即可。

#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 43210
int phi[MAXN],prime[MAXN];
bool vis[MAXN];
void euler(){
phi[1]=1;
int tot=0;
for(int i=2; i<MAXN; ++i){
if(!vis[i]){
prime[tot++]=i;
phi[i]=i-1;
}
for(int j=0; j<tot; ++j){
if(i*prime[j]>MAXN) break;
vis[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}
int main(){
euler();
int n;
scanf("%d",&n);
if(n==1){
putchar('0');
return 0;
}
int res=2;
for(int i=2; i<=n; ++i){
res+=phi[i-1]<<1;
}
printf("%d",res-1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: