Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are
F2 = {1/2}
F3 = {1/3, 1/2, 2/3}
F4 = {1/4, 1/3, 1/2, 2/3, 3/4}
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5}
You task is to calculate the number of terms in the Farey sequence Fn.
Input
There are several test cases. Each test case has only one line, which contains a positive integer n (2 <= n <= 106). There are no blank lines between cases. A line with a single 0 terminates the input.
Output
For each test case, you should output one line, which contains N(n) ---- the number of terms in the Farey sequence Fn.
Sample Input
23450
Sample Output
1359
題目分析:
這個題目就是要求 :小於n並且與n互素的個數,也就是歐拉定理
如果n=(p^x1)*(p2^x2)*(p3^x3)那麼 小於n與n互素的元素個數是n*(1-1/x1)*(1-1/x2)*(1-1/x3) ,(p1,p2,p3為素數)這就是歐拉公式
我們只需要根據歐拉公式來求和就可以。
首先把所有素數找出來存在一個數組裡面,然後用n來除這些素數(n逐漸層小),知道n小於某個素數的平方,那麼n就是最後一個因子,然後根據上面的公式來計算。
/**/#include<iostream>#include <iomanip>#include<stdio.h>#include<cmath>#include<iomanip>#include<list>#include <map>#include <vector>#include <string>#include <algorithm>#include <sstream>#include <stack>#include<queue>#include<string.h>#include<set>using namespace std;unsigned long long data[1000001];bool flag[1000001];vector<int> prime;void init(){for(int i=2;i<sqrt(1000001.0);i++){if(flag[i]==true)continue;for(int j=2;i*j<1000001;j++)flag[i*j]=true;}for(int i=2;i<1000001;i++){if(flag[i]==false)prime.push_back(i);}}int main(){init();data[0]=0;for(int i=1;i<1000001;i++){int value=i+1;if(flag[value]==false){data[i]=data[i-1]+value-1;continue;}int value1=i+1;//儲存最後的結果for(int j=0;j<prime.size()&&prime[j]<=value;j++){if(prime[j]*prime[j]>value)//剩餘的value是一個素數,沒有這句逾時{value1=value1/value*(value-1);break;}if(value%prime[j]==0){value=value/prime[j];value1=value1/prime[j]*(prime[j]-1);while(value%prime[j]==0)value=value/prime[j];}}data[i]=data[i-1]+value1;}int n;while(cin>>n&&n!=0){cout<<data[n-1]<<endl;}}