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;
}

 

posted @ 2014-09-19 13:50  PlasticSpirit  阅读(434)  评论(0编辑  收藏  举报