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

  

你可能感兴趣的:(APP)