HDU 1695 GCD 【莫比乌斯反演例题】

GCD
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4291 Accepted Submission(s): 1502

 

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
2008 “Sunline Cup” National Invitational Contest

让你求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d)。
没办法,被老师派到了这个数论专题,可怜我初三还没上,对于sigma还是懵逼的,都得硬着头上。
我就是跟着这篇文章学的:点我
讲得很好,适合我这种数学差的蒟蒻。
进入正题
唯一接触过的能用的是容斥原理,欧拉函数
莫比乌斯反演是什么?不知道。于是去学

这题求[1,n],[1,m]gcd为k的对数。而且没有顺序。

转化之后就是[1,n/k],[1,m/k]之间互质的数的个数。

用莫比乌斯反演就很容易求了。

为了去除重复的,去掉一部分就好了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=1000000;
bool check[maxn+10];
int prime[maxn+10];
int U[maxn+10];//表示系数
void get_Mobius()
{
    memset(check,false,sizeof(check));
    U[1]=1;
    int tot=0;
    for(int i=2;i<=maxn;i++)
    {
        if(check[i]==0)
        {
            prime[tot++]=i;
            U[i]=-1;//本身是个质数,1个质数乘积
        }
        for(int j=0;j<tot;j++)
        {
            if(i*prime[j]>maxn)break;
            check[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                U[i*prime[j]]=0;//除开质数的两种情况
                break;
            }
            else
            {
                U[i*prime[j]]=-U[i];//多了一个数的乘积,与前一个相反
            }
        }
    }
}
/*
只要让F(t)=满足gcd(x,y)%t==0的数对个数
f(t)=满足gcd(x,y)=t的数对个数,则F(t)和f(t)就存在莫比乌斯反演的关系了。显然F(t)=(b/t)*(d/t)
因为如果gcd(x,y)=1,则gcd(x?k,y?k)=k,所以我们把b和d同时除以k,
得到的f(1)再去重就是答案。令lim=min(b/k,d/k),就根据我给出的莫比乌斯反演第二个公式,
*/
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int T;
    int a,b,c,d,k;
    get_Mobius();
    scanf("%d",&T);
    for(int ii=1;ii<=T;ii++)
    {
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        if(k==0)
        {
            printf("0\n");
            continue;
        }
        b/=k;a/=k;
        d/=k;c/=k;
        if(b>d)swap(b,d);
        long long ans1=0;
        for(int i=1;i<=b;i++)
            ans1+=(long long)U[i]*(b/i)*(d/i);//带入 G(n) 的公式 有  F(1) = sigma(U[i]*(a/i)*(b/i)) (1<=i<=N)
        long long ans2=0;
        for(int i=1;i<=b;i++)
            ans2+=(long long)U[i]*(b/i)*(b/i);//相同的数啊如此重复的状况
        ans1-=ans2/2;
        printf("%lld\n",ans1);
    }
    return 0;
}

by_lmy

时间: 2024-11-07 04:14:35

HDU 1695 GCD 【莫比乌斯反演例题】的相关文章

HDU 1695 GCD 莫比乌斯第二发

题意:求[1,b]和[1,d]内公约数为k的对数(错了N发之后才看到a和c为1...) 解一:容斥原理和欧拉函数 http://www.cnblogs.com/kuangbin/p/3269182.html 参考大神的文章吧,我没写=-= 解二:莫比乌斯 设f[x]为GCD(a,b)=k的对数 F[x]为k|x的对数 所以b,d均除k就是求所有GCD为1的对数 sum+=sigema(mu[i]*(b/i)*(d/i)) #include <stdio.h> #include <stri

hdu 1695 GCD 莫比乌斯

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9765    Accepted Submission(s): 3652 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)

HDU 1695 GCD 欧拉函数+容斥原理+质因数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:在[a,b]中的x,在[c,d]中的y,求x与y的最大公约数为k的组合有多少.(a=1, a <= b <= 100000, c=1, c <= d <= 100000, 0 <= k <= 100000) 思路:因为x与y的最大公约数为k,所以xx=x/k与yy=y/k一定互质.要从a/k和b/k之中选择互质的数,枚举1~b/k,当选择的yy小于等于a/k时,可以

HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理)

GCD 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 t

HDU 1695 GCD (莫比乌斯反演)

传送门 GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9749    Accepted Submission(s): 3648 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)

HDU 1695 GCD(容斥 or 莫比乌斯反演)

这题可以用容斥做,然而效率并不高.. 于是学了下莫比乌斯反演(资料百度找) 求出mo数组后 设f(x)为gcd为x的种数 F(x)为gcd为x倍数的种数 那么显然F(x) = (b / x) * (d / x) 莫比乌斯反演之后,得到f(x) = sum(mo[i] * F(i)). 然后还要容斥减去对称重复的.对称重复的情况为min(b, d)小的中,求一遍除2,(因为存在x = y的情况只有(1,1)一种) 最后还要注意特判下k == 0的情况 代码: #include <cstdio>

莫比乌斯二连 HDU 5212 Code &amp; HDU 1695 GCD

莫比乌斯的模板题 都是差不多的 F(m)为gcd(i,j) = m(i∈[1,m],j∈[1,n])的个数 f(m) = ∑(m\d) F(d)  意义为gcd(i,j)为m的倍数的个数 运用莫比乌斯反演得到 F(m) = ∑(m\d)μ(d/m) * f(d) #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std;

HDU 4746 Mophues (莫比乌斯反演应用)

Mophues Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327670/327670 K (Java/Others) Total Submission(s): 980    Accepted Submission(s): 376 Problem Description As we know, any positive integer C ( C >= 2 ) can be written as the multiply of

HDU - 6715 - 算术 = 莫比乌斯反演

http://acm.hdu.edu.cn/showproblem.php?pid=6715 题意: 求:\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\mu(lcm(i,j))\),其中n,m是1e6范围内,10组. 不会,想了很久,也不知道假在哪里.大概是一开始方向就错了. 正解: 所求:\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\mu(lcm(i,j))\) 即:\(\sum\limits_{i=1}^