码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-02-06 01:39:40      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

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即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 #define MAXN 43210
 5 int phi[MAXN],prime[MAXN];
 6 bool vis[MAXN];
 7 void euler(){
 8     phi[1]=1;
 9     int tot=0;
10     for(int i=2; i<MAXN; ++i){
11         if(!vis[i]){
12             prime[tot++]=i;
13             phi[i]=i-1;
14         }
15         for(int j=0; j<tot; ++j){
16             if(i*prime[j]>MAXN) break;
17             vis[i*prime[j]]=1;
18             if(i%prime[j]==0){
19                 phi[i*prime[j]]=phi[i]*prime[j];
20                 break;
21             }else{
22                 phi[i*prime[j]]=phi[i]*(prime[j]-1);
23             }
24         }
25     }
26 }
27 int main(){
28     euler();
29     int n;
30     scanf("%d",&n);
31     if(n==1){
32         putchar(0);
33         return 0;
34     }
35     int res=2;
36     for(int i=2; i<=n; ++i){
37         res+=phi[i-1]<<1;
38     }
39     printf("%d",res-1);
40     return 0;
41 } 

 

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

标签:

原文地址:http://www.cnblogs.com/WABoss/p/5183675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!