poj 2773 利用欧拉函数求互质数

题意:找到与n互质的第 k个数

开始一看n是1e6 敲了个暴力结果tle了,后来发现k达到了 1e8

所以需要用到欧拉函数。

我们设小于n的 ,与n互质的数为  (a1,a2,a3.......a(phi(n)))

那么显然,在区间  [ k*n , (k+1)*n ]内的互质数即为 k*n+(a1,a2,a3.......a(phi(n)))

所以只需要求出 (a1,a2,a3.......a(phi(n))) 就可以利用欧拉函数快速找到后面的数

代码如下:

#include <iostream>

#include <stdio.h>

#include<string.h>

#include<algorithm>

#include<string>

#include<ctype.h>

using namespace std;

#define maxn 1000000

int euler[maxn+1];

void phi()

{

    for(int i=1;i<=maxn;i++)

        euler[i]=i;

    for(int i=2;i<=maxn;i+=2)

        euler[i]/=2;

    for(int i=3;i<=maxn;i++)

    {

        if(euler[i]==i) //未被筛到。是素数,则用此素数来筛

        {

            for(int j=i;j<=maxn;j+=i)

            {

                euler[j]=euler[j]/i*(i-1);

            }

        }

    }

    return ;

}

int gcd(int a,int b)

{

    return b?gcd(b,a%b):a;

}

int main()

{

    int n,k;

    phi();

    while(scanf("%d%d",&n,&k)!=EOF)

    {

        int t=k/euler[n];

        int p=k%euler[n];

        if(p==0)

        {

            t--;

            p=euler[n];

        }

        int i;

        for(i=1;i<=n;i++)

        {

            if(gcd(i,n)==1)

                p--;

            if(p==0)

                break;

        }

        printf("%I64d\n",i+(long long)t*n);

    }



    return 0;

}

 

你可能感兴趣的:(poj)