您的位置:首页 > 其它

HDU_1695_GCD(欧拉函数+容斥原理+DFS)

2013-09-05 17:34 316 查看


GCD

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

Total Submission(s): 4337 Accepted Submission(s): 1522



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

HintFor 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

2008 “Sunline Cup”
National Invitational Contest

Recommend

wangye

题型:数论+组合数学

题意:在1~b和1~d两个区间中各取一个数,这两个数的GCD为k,问有多少对这样的数。

分析

先将问题化简一下,将这两个区间都缩小k倍,即b/=k、d/=k,那么求GCD=k就变成了就GCD=1,也就是求两个互质的数的对数。

设1~b的范围小,我们可以枚举范围1~d,枚举过程中比b小的部分可以用欧拉函数求出,为phi[i];比b大的部分则需要通过容斥原理来求。

先回顾一下容斥原理的内容:

两个集合的容斥关系公式:A∪B = A+B - A∩B (∩:重合的部分)

三个集合的容斥关系公式:A∪B∪C = A+B+C - A∩B - B∩C - C∩A +A∩B∩C

回到题目中,区间中与i不互质的个数 = (区间中i的每个质因数的倍数个数)-(区间中i的每两个质因数乘积的倍数)+(区间中i的每3个质因数的成绩的倍数个数)-(区间中i的每4个质因数的乘积)+...

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define LL __int64
using namespace std;
const int MAXN=123456;
LL phi[MAXN];
int p[MAXN][15];
int cnt[MAXN];

void init()
{
int i,j;
phi[1]=1;
for(i=2;i<MAXN;i++)//筛选法得到数的素因子及每个数的欧拉函数值
{
if(!phi[i])
{
for(j=i;j<MAXN;j+=i)
{
if(!phi[j])
phi[j]=j;
phi[j]=phi[j]*(i-1)/i;
p[j][cnt[j]++]=i;
}
}
phi[i]+=phi[i-1];
}
}

LL dfs(int x,int b,int q){//求b内与q不互质的个数
LL res=0;
int i;
for(i=x;i<cnt[q];i++){
res+=(b/p[q][i]-dfs(i+1,b/p[q][i],q));
}
return res;
}

int main()
{
int a,b,c,d,k,t,time;
init();
scanf("%d",&t);
time=0;
while(t--){
time++;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
if(k==0){
printf("Case %d: 0\n",time);
continue;
}
b/=k;
d/=k;
if(b>d){//promise b is larger;
int tmp=b;
b=d;
d=tmp;
}
LL sum=phi[b];
for(int i=b+1;i<=d;i++){
sum+=(b-dfs(0,b,i));
}
printf("Case %d: %I64d\n",time,sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: