校赛

Problem D: 求互质对数

Description

1到n中,任意选择两个数,使其互质,问总共有多少种选择方法,注意(1,2)和(2,1)是同一种方案

Input

输入有多组数据,第一行输入T(T<=100000)

接下来每一行输入一个n,(1<=n<=1000)

Output

每一行输出一个方案数

Sample Input


2

Sample Output

1

题解

欧拉函数模板





欧拉函数

  欧拉函数,它又称为Euler's totient function、φ函数、欧拉商数等,对正整数n,欧拉函数是小于n且和n互质的正整数(包括1)的个数。例如Euler(8)=4,因为1,3,5,7均和8互质,下面用E(n)表示欧拉函数的值。

  Euler函数表达通式:E(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数,x是不为0的整数。E(1)=1(唯一和1互质的数就是1本身)。 
  欧拉公式的延伸:一个数的所有质因子之和是 E(n)*n/2。
  欧拉定理:对于互质的正整数a和n,有a^E(n) ≡ 1 mod n。
  欧拉函数是积性函数——若m,n互质,E(m*n)=E(m)*E(n)。
  若n是质数p的k次幂,E(n)=p^k-p^(k-1)=(p-1)*p^(k-1),因为除了p的倍数外,其他数都跟n互质。
  特殊性质:当n为奇数时,E(2n)=E(n)

先是直接根据公式求欧拉函数的值:


//离线打表
//筛选法求欧拉函数,时间复杂度O(nloglogn)
//跟埃式筛法求素数差不多
#include 

using namespace std;

const int MAXN = 100010;
int a[MAXN];

void init()
{
    for(int i = 1 ; i <= MAXN ; i++)
        a[i] = i;
    a[1] = 0;
    for(int i = 1 ; i <= MAXN ; i++)
    {
        if(a[i] == i)
        {
            for(int j = i ; j <= MAXN ; j += i)
                a[j] = a[j] / i * (i - 1);
        }
    }
}
scanf ( "%d" ,&casenum); for (casei= 1 ;casei<=casenum;++casei) { int n; scanf ( "%d" ,&n); printf ( "%d\n" ,phi[n]); } return 0 ;
};
   

你可能感兴趣的:(水题)