2190. [SDOI2008]儀仗隊【歐拉函數】
阿新 • • 發佈:2018-04-10
www. 歐拉 一個 運動會 esc pre 訓練 現在 int
那麽很容易發現:
一個人如果是不可視的,那麽他的坐標(x,y)一定含有公約數k
使得一個人(x/k,y/k)可以擋住他。
那麽只要一個人的橫縱坐標互質,就是可以被看見的
那麽問題就轉化成了對於每個1~n中的數,有多少個1~n的數與其互質
然後我們又可以發現答案關於(0,0)->(n,n)軸對稱
所以我們只算一半即可。
然後就可以把問題轉化為求和歐拉函數的φ(1)~φ(n)了
註意n=1的時候特判一下
Description
作為體育委員,C君負責這次運動會儀仗隊的訓練。儀仗隊是由學生組成的N * N的方陣,為了保證隊伍在行進中整齊劃一,C君會跟在儀仗隊的左後方,根據其視線所及的學生人數來判斷隊伍是否整齊(如下圖)。 現在,C君希望你告訴他隊伍整齊時能看到的學生人數。
Input
共一個數N。
Output
共一個數,即C君應看到的學生人數。
Sample Input
4Sample Output
9HINT
【數據規模和約定】 對於 100% 的數據,1 ≤ N ≤ 40000
首先設左下角坐標為(0,0)
一個人如果是不可視的,那麽他的坐標(x,y)一定含有公約數k
使得一個人(x/k,y/k)可以擋住他。
那麽只要一個人的橫縱坐標互質,就是可以被看見的
那麽問題就轉化成了對於每個1~n中的數,有多少個1~n的數與其互質
然後我們又可以發現答案關於(0,0)->(n,n)軸對稱
所以我們只算一半即可。
然後就可以把問題轉化為求和歐拉函數的φ(1)~φ(n)了
註意n=1的時候特判一下
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int ans,n,phi[40005]; 5 6 void Euler() 7 { 8 phi[1]=1; 9 for (int i=2;i<=40000;++i) 10 if (!phi[i]) 11 for (int j=i;j<=40000;j+=i) 12 { 13 if (!phi[j]) phi[j]=j; 14 phi[j]=phi[j]/i*(i-1); 15 } 16 } 17 18 int main() 19{ 20 scanf("%d",&n); 21 Euler(); 22 for (int i=1;i<n;++i) 23 ans+=phi[i]; 24 printf("%d",ans*2+(n!=1)); 25 }
2190. [SDOI2008]儀仗隊【歐拉函數】