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
",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
",iCase,ans1);
    }
    return 0;
}

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

原文地址:https://www.cnblogs.com/zhangmingzhao/p/7253123.html