poj 2773 Happy 2006——欧拉函数
给定m, k(1 <= m <= 1000000), K(1 <= K <= 100000000), 询问第k个与m互质的数。
欧拉函数的应用。首先是求出m的欧拉函数值phi[m],可知区间[1, m - 1]中有phi[m]个数与m互质。同样,在区间[n*m + 1, (n + 1) * m]中必然也有phi[m]个数与m互质,并且这phi[m]个数与[1 - m - 1]的phi[m]个数是"一一对应"的。
所以只要通过k / phi[m]找到第n个区间,然后再枚举区间中的数就可以找到第k个与m互质的数。
先开始当m=1时,我输出的是k+1,wa了几次,后来改成k就过了……真是不知道怎么办才好……
a27400 | 2773 | Accepted | 396K | 1547MS | G++ | 973B | 2011-09-05 20:13:16 |
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
long long gcd(long long a,long long b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
long long euler(long long n)
{
long long i;
long long total=n;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
total=total/i*(i-1);
while(n%i==0)
{
n/=i;
}
}
}
if(n!=1)
total=total/n*(n-1);
return total;
}
int main(void)
{
long long m,k;
while(scanf("%lld %lld",&m,&k)==2)
{
if(m==1)
{
printf("%lld\n",k);
continue;
}
long long temp=euler(m);
long long n=k/temp;
k-=temp*n;
if(k==0)
{
k=temp;
n--;
}
long long i=n*m+1;
long long total=0;
for(;;i++)
{
long long a=m;
long long b=i;
if(a<b)
swap(a,b);
if(gcd(a,b)==1)
{
total++;
if(total==k)
{
printf("%lld\n",i);
break;
}
}
}
}
return 0;
}