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) = 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).

题目大意:

求 [1,b] 和 [1,d] 区间中 GCD(x,y)==k 的对数,GCD(3,2)和GCD(2,3) 被认为是一样的。

解题思路:

这个题目,我当时是用容斥原理 + 欧拉函数写的,过了 现在学到莫比乌斯反演又打算用这个写,因为这算是一个入门的题目,

那么我们就想办法来构造那两个函数 f(n) 和 F(n) ,那么我们现在来设 f(k)表示的是GCD(x,y)==k 的对数,其中

(1<=x<=b,1<=y<=d) 为了保证最后的唯一性,那么我们默认为 b<=d,那么我们再来构造 F(n) ,设 F(k)

是GCD(x,y)==k的倍数的对数 那么显然有 F(k)=floor(bk)?floor(dk) 那么根据莫比乌斯反演有:

f(i)=∑i|kmu(ki)?F(k)=∑i|dmu(ki)?floor(bk)?floor(dk)

然后进行去重就行了。

My Code:

/**
2016 - 08 - 16 上午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 1e6+5;
const int MOD = 1e9+7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL Scan_LL()///输入外挂
{
    LL res=0,ch,flag=0;
    if((ch=getchar())==‘-‘)
        flag=1;
    else if(ch>=‘0‘&&ch<=‘9‘)
        res=ch-‘0‘;
    while((ch=getchar())>=‘0‘&&ch<=‘9‘)
        res=res*10+ch-‘0‘;
    return flag?-res:res;
}
int Scan_Int()///输入外挂
{
    int res=0,ch,flag=0;
    if((ch=getchar())==‘-‘)
        flag=1;
    else if(ch>=‘0‘&&ch<=‘9‘)
        res=ch-‘0‘;
    while((ch=getchar())>=‘0‘&&ch<=‘9‘)
        res=res*10+ch-‘0‘;
    return flag?-res:res;
}
void Out(LL a)///输出外挂
{
    if(a>9)
        Out(a/10);
    putchar(a%10+‘0‘);
}
int mu[MAXN], p[MAXN], k;
bool prime[MAXN];
void Mobius()
{
    memset(prime, 0, sizeof(prime));
    mu[1] = 1;
    k = 0;
    for(int i=2; i<MAXN; i++)
    {
        if(!prime[i])
        {
            p[k++] = i;
            mu[i] = -1;
        }
        for(int j=0; j<k&&i*p[j]<MAXN; j++)
        {
            prime[i*p[j]] = 1;
            if(i%p[j] == 0)
            {
                mu[i*p[j]] = 0;
                break;
            }
            mu[i*p[j]] = -mu[i];
        }
    }
}

int main()
{
    Mobius();
    int T;
    T = Scan_Int();
    for(int cas=1; cas<=T; cas++)
    {
        LL a, b, c, d, k;
        a = Scan_LL();
        b = Scan_LL();
        c = Scan_LL();
        d = Scan_LL();
        k = Scan_LL();
        if(k==0LL || k>b || k>d)
        {
            printf("Case %d: 0\n",cas);
            continue;
        }
        d /= k;
        b /= k;
        if(b > d)
            swap(b, d);
        LL ret = 0, ans = 0;
        for(LL i=1; i<=b; i++)
            ret += mu[i]*(b/i)*(d/i);
        for(LL i=1; i<=b; i++)
            ans += mu[i]*(b/i)*(b/i);
        ret -= (ans>>1LL);
        printf("Case %d: %I64d\n",cas,ret);
    }
    return 0;
}
时间: 2024-08-24 23:59:18

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 【莫比乌斯反演例题】

GCDTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4291 Accepted Submission(s): 1502   Problem DescriptionGiven 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k.

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