歐拉函數:web
大意:表示的是一個數有幾個與它互質的數,好比8的歐拉數爲4(1 3 5 7);函數
例題:spa
Descriptioncode
A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin, is visible from the origin if the line from (0, 0) to (x, y) does not pass through any other lattice point. For example, the point (4, 2) is not visible since the line from the origin passes through (2, 1). The figure below shows the points (x, y) with 0 ≤ x, y ≤ 5 with lines from the origin to the visible points.orm
Write a program which, given a value for the size, N, computes the number of visible points (x, y) with 0 ≤ x, y ≤ N.ip
Inputinput
The first line of input contains a single integer C (1 ≤ C ≤ 1000) which is the number of datasets that follow.it
Each dataset consists of a single line of input containing a single integer N (1 ≤ N ≤ 1000), which is the size.io
Outputclass
For each dataset, there is to be one line of output consisting of: the dataset number starting at 1, a single space, the size, a single space and the number of visible points for that size.
Sample Input
4 2 4 5 231
Sample Output
1 2 5 2 4 13 3 5 21 4 231 32549
題目大意:一個(n+1)*(n+1)的點陣,問多少點能被點(0,0)看到。若是(0,0)到(i,j)的連線被點擋住就算看不到。
先畫一條(0, 0)到(n, n)的線,把圖分紅兩部分,兩部分是對稱的,只需算一部分就好。取右下半,這一半里的點(x, y)知足x >= y能夠經過歐拉函數計算第k列有多少點可以連到(0, 0)若x與k的最大公約數d > 1,則(0, 0)與(x, k)點的臉先一定會經過(x/d, k/d),就被擋住了因此能連的線的數目就是比k小的、和k互質的數的個數,而後就是歐拉函數。因爲是對稱的,因此只需算一半的數量就夠了。第k列上的一個點的縱座標爲d,若gcd(k,d) != 1,則遠帶你與該點的連線必須經過(k/gcd,d/gcd),確定被擋住了。
由此咱們能夠獲得遞推公式 res1[i] = res1[i-1] + 2*phi[i];其中phi[i]是第i列上能看到的點的個數,
由此便轉化爲了歐拉函數:
code:
#include<stdio.h> #define MMAX 1000006 int e[MMAX]; void f()//歐拉函數 { int i,j; for(i=1; i<MMAX; i++) e[i]=i; for(j=2; j<MMAX; j++) if(e[j]==j) for(i=j; i<MMAX; i+=j) e[i]=e[i]/j*(j-1); } int main() { int n,i,t,case1=1; f(); scanf("%d",&t); while(t--) { scanf("%d",&n); long long sum=0; for(i=2; i<=n; i++)//n-1列加一塊兒 sum+=e[i]; printf("%d %d %lld\n",case1++,n,sum*2+3); } return 0; }