您的位置:首页 > 其它

HDU2588_大区间_GCD_欧拉函数应用

2012-07-19 02:03 441 查看
/*
*Time: 0 ms
*题目大意:
*        输入m, n(n < 1000000000),求1~n之间中gcd(x, n) >=m 的x个数。
*解题思路:
*        找出N的所有大于等于M的因子(x1,x2,x3.....xi),然后设k=N/xi;
*        下面只需找出小于k且与k互质的数。
*        因为:设y与k互质且小于k,那么gcd(y*xi,k*xi)=xi;
*        (xi为N的因子,且xi大于等于M)。
*/


View Code

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

const int MAX = 1000000;
int factor[MAX];

int init(int n)
{
int cnt = 0;
int e = (int)sqrt((double)n);
int i;
for(i = 1; i < e; i++)
{
if(n % i == 0)
{
factor[cnt++] = i;
factor[cnt++] = n / i;
}
}
if(n % i == 0)
factor[cnt++] = i;
sort(factor, factor + cnt);
return cnt;
}

int euler(int x)
{
// 就是公式
int i, res = x;
for (i = 2; i < (int)sqrt(x * 1.0) + 1; i++)
if(x % i == 0)
{
res = res / i * (i - 1);
while (x % i == 0) x /= i; // 保证i一定是素数
}
if (x > 1)
res = res / x * (x - 1);
return res;
}

int main(void)
{
int cas;
scanf("%d", &cas);
while(cas--)
{
int m, n;
scanf("%d %d", &n, &m);
int len = init(n);
int i;
for(i = 0; i < len; i++)
{
if(factor[i] >= m)
break;
}
int ans = 0;
for(; i < len; i++)
{
int t = n / factor[i];
ans += euler(t);
}
cout << ans << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: