首页 > 其他 > 详细

[HDU 1695] GCD

时间:2015-04-27 19:59:29      阅读:242      评论:0      收藏:0      [点我收藏+]

GCD

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 6805    Accepted Submission(s): 2491

Problem Description
Given 5 integers: a, b, c, d, k, you‘re to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you‘re only required to output the total number of different number pairs. Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.
Yoiu can assume that a = c = 1 in all test cases.
 

 

Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 cases. Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.
 

 

Output
For each test case, print the number of choices. Use the format in the example.
 

 

Sample Input
2 1 3 1 5 1 1 11014 1 14409 9
 

 

Sample Output
Case 1: 9 Case 2: 736427
Hint
For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
 

 

Source
 

  容斥定理、具体见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define ll long long
#define N 100000

int tot;
int prime[N+10];
bool isprime[N+10];
int phi[N+10];
void prime_pri()
{
    tot=0;
    phi[1]=1;
    memset(isprime,true,sizeof(isprime));
    isprime[0]=isprime[1]=false;
    for(int i=2;i<=N;i++)
    {
        if(isprime[i])
        {
            prime[tot++]=i;
            phi[i]=i-1;
        }
        for(int j=0;j<tot;j++)
        {
            if(i*prime[j]>N) break;
            isprime[i*prime[j]]=false;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else
            {
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
}
int fatcnt;
int factor[N][2];
int getfactors(int x)
{
    fatcnt=0;
    int tmp=x;
    for(int i=0;prime[i]<=tmp/prime[i];i++)
    {
        factor[fatcnt][1]=0;
        if(tmp%prime[i]==0)
        {
            factor[fatcnt][0]=prime[i];
            while(tmp%prime[i]==0)
            {
                factor[fatcnt][1]++;
                tmp/=prime[i];
            }
            fatcnt++;
        }
    }
    if(tmp!=1)
    {
        factor[fatcnt][0]=tmp;
        factor[fatcnt++][1]=1;
    }
    return fatcnt;
}
int cal(int n,int m) //求1到n中与m互质的数的个数
{
    int tmp,cnt,ans=0;
    getfactors(m);
    for(int i=1;i<(1<<fatcnt);i++) //0表示不选择因子
    {
        cnt=0;
        tmp=1;
        for(int j=0;j<fatcnt;j++)
        {
            if(i&(1<<j))
            {
                cnt++;
                tmp*=factor[j][0];
            }
        }
        if(cnt&1) ans+=n/tmp;
        else ans-=n/tmp;
    }
    return n-ans;
}
int main()
{
    prime_pri();
    int T,iCase=1;
    int a,b,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d",&a,&a,&b,&b,&k);
        if(k==0) //除0特判
        {
            printf("Case %d: 0\n",iCase++);
            continue;
        }
        a/=k,b/=k;
        if(a>b) swap(a,b);
        ll ans=0;
        for(int i=1;i<=b;i++)
        {
            if(i<=a) ans+=phi[i];
            else ans+=cal(a,i);
        }
        printf("Case %d: %lld\n",iCase++,ans);
    }
    return 0;
}

 

[HDU 1695] GCD

原文:http://www.cnblogs.com/hate13/p/4461066.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!