计蒜客-T1581

题目

这里我们定义 φ(n)表示所有小于等于 n 与 n 互质数的个数。

例如 φ(10)=4,因为我们可以在 1∼10 中找到 1,3,7,9与 10 互质。
输入格式

第一行输入一个整数 t,表示测试数据组数。

接下来 t 行,每行有一个整数 n。
输出格式

对于每组测试数据输出 φ(n)。
数据范围

1≤t≤106, 1≤n≤106

输出时每行末尾的多余空格,不影响答案正确性
样例输入

3
2
10
100

样例输出

1
4
40

思路

1.欧拉函数的模板题,由于多组数据,所以要用到筛法快速求,这里使用欧拉筛
2.先将106以内数筛出来,然后直接输出
3.数据输入量大,所以c++输入会超时,要用c输入
可参考我的博客素数筛与欧拉函数入门

代码

#include 
#include
using namespace std;
const int maxx=1e6+7,inf=0x3f3f3f3f;
typedef long long ll;
ll phi[1000010],vis[1000010],prime[1000010];
int euler(int n)
{
    int cnt=0;
    phi[1]=1;//1要特判
    for (int i=2; i<=n; i++)
    {
        if (vis[i]==0)//这代表i是质数
        {
            prime[cnt++]=i;  phi[i]=i-1;   //性质1
        }
        for (int j=0; j<cnt&&prime[j]*i<=n; j++)
        {
            vis[i*prime[j]]=1;
            if (i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];//性质4
                break;
            }
            else  phi[i*prime[j]]=phi[i]*phi[prime[j]];//性质3
        }
    }        return cnt;
}


int main()
{
    int t,a;
    scanf("%d",&t);
    euler(1000005);
    while(t--)
    {
        scanf("%d",&a);
        printf("%lld\n",phi[a]);
    }
}

你可能感兴趣的:(c++)