HDU 1695 莫比乌斯思想基础题

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1695

莫比乌斯反演参考资料:http://www.cnblogs.com/chenyang920/p/4811995.html

           https://baike.baidu.com/item/%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%8F%8D%E6%BC%94

我们现在就是求f(1),即x为1,所以就是所有的d都满足,即枚举所有的d~(1-b),注意减去重复的部分。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000000;
bool check[MAXN+10];
int prime[MAXN+10];
int mu[MAXN+10];
void Moblus()
{
    memset(check,false,sizeof(check));
    mu[1] = 1;
    int tot = 0;
    for(int i = 2; i <= MAXN; i++)
    {
        if( !check[i] )
        {
            prime[tot++] = i;
            mu[i] = -1;
        }
        for(int j = 0; j < tot; j++)
        {
            if(i * prime[j] > MAXN) break;
            check[i * prime[j]] = true;
            if( i % prime[j] == 0)
            {
                mu[i * prime[j]] = 0;
                break;
            }
            else
            {
                mu[i * prime[j]] = -mu[i];
            }
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);

    int T;
    int a,b,c,d,k;
    Moblus();
    scanf("%d",&T);
    int iCase = 0;
    while(T--)
    {
        iCase++;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        if(k == 0)
        {
            printf("Case %d: 0\n",iCase);
            continue;
        }
        b /= k;
        d /= k;
        if(b > d)
            swap(b,d);
        long long ans1 = 0;
        for(int i = 1; i <= b; i++)
            ans1 += (long long)mu[i]*(b/i)*(d/i);
        long long ans2 = 0;
        for(int i = 1; i <= b; i++)
            ans2 += (long long)mu[i]*(b/i)*(b/i);
        ans1 -= ans2/2;
        printf("Case %d: %I64d\n",iCase,ans1);
    }
    return 0;
}

然后就是可以用分块优化了

时间: 2024-12-28 02:34:53

HDU 1695 莫比乌斯思想基础题的相关文章

hdu 1695 莫比乌斯反演

hdu 1695 莫比乌斯反演 题意: 给出a,b,c,d,k, 求满足a <= x <= b && c <= y <= d && gcd(x,y)=k 的数对(x,y)的对数. 限制: a=c=1; 0 < b,c <= 1e5; (n1,n2) 和 (n2,n1) 算为同种情况 思路: 其实是求满足1 <= x <= b/k && 1 <= y <= d/k && gcd(x,y

hdu 2680 最短路基础题 spfa实现 算法总结

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2680 题目大意,就是一个人可以从多个起点开始出发,看到终点的最短路是多少..只有可以运用和hdu2066一样的思想,对于每个起点可以看成是跟最最开始的点之间有一条权值为0的边.可以把最开始的点记做0点.那这样就可以使用单源最短路了.之前都没有用过spfa,今天来运用了一下. 算法大致流程是用一个队列来进行维护.初始时将源加入队列.每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松

HDU 1695 (莫比乌斯反演) GCD

题意: 从区间[1, b]和[1, d]中分别选一个x, y,使得gcd(x, y) = k, 求满足条件的xy的对数(不区分xy的顺序) 分析: 虽然之前写过一个莫比乌斯反演的总结,可遇到这道题还是不知道怎么应用. 这里有关于莫比乌斯反演的知识,而且最后的例题中就有这道题并给出了公式的推导. 1 #include <cstdio> 2 #include <algorithm> 3 typedef long long LL; 4 5 const int maxn = 1000000

HDU 2063 最大匹配的基础题

中文题,题目大意不说了. 思路:就是寻找最大匹配,最大匹配就是每次找增广路,如果存在增广,那就把增广路上面的边全部都翻转即可.这样说明能多匹配一个,+1即可. //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #defi

HDU 2966 Aragorn&#39;s Story 树链剖分第一题 基础题

Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges c

hdu 1695 容斥原理或莫比乌斯反演

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

Print Article hdu 3507 一道斜率优化DP 表示是基础题,但对我来说很难

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 4990    Accepted Submission(s): 1509 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antique

Jam&#39;s balance HDU - 5616 (01背包基础题)

Jim has a balance and N weights. (1≤N≤20) The balance can only tell whether things on different side are the same weight. Weights can be put on left side or right side arbitrarily. Please tell whether the balance can measure an object of weight M. In

莫比乌斯二连 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;