首页 > 代码库 > poj 2773 利用欧拉函数求互质数

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 1000000int 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 2773 利用欧拉函数求互质数