BZOJ 2301 [HAOI2011]Problem b 莫比乌斯反演

传送门
类似题目
简单容斥

  像上一篇题解一样定义 A(n,m),则答案为:

A(b,d)A(a,d)A(b,c)+A(a,c)

参考代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
typedef long long INT;
using std::cin;
using std::cout;
using std::endl;
INT readIn()
{
    INT a = 0;
    bool minus = false;
    char ch = getchar();
    while (!(ch == '-' || (ch >= '0' && ch <= '9'))) ch = getchar();
    if (ch == '-')
    {
        minus = true;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        a = a * 10 + (ch - '0');
        ch = getchar();
    }
    if (minus) a = -a;
    return a;
}
void printOut(INT x)
{
    char buffer[20];
    INT length = 0;
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    do
    {
        buffer[length++] = x % 10 + '0';
        x /= 10;
    } while (x);
    do
    {
        putchar(buffer[--length]);
    } while (length);
    putchar('\n');
}

const int maxn = int(5e4);
int mu[maxn + 5];
int prime[maxn + 5];
bool isntPrime[maxn + 5];
void init()
{
    mu[1] = 1;
    isntPrime[1] = true;
    int& num = prime[0];
    for (int i = 2; i <= maxn; i++)
    {
        if (!isntPrime[i])
        {
            prime[++num] = i;
            mu[i] = -1;
        }
        for (int j = 1, p = prime[j], s = i * p; j <= num && s <= maxn; j++, p = prime[j], s = i * p)
        {
            isntPrime[s] = true;
            if (i % p)
            {
                mu[s] = -mu[i];
            }
            else
            {
                mu[s] = 0;
                break;
            }
        }
    }
    for (int i = 2; i <= maxn; i++)
        mu[i] += mu[i - 1];
}

int l1, r1, l2, r2, k;

long long solve(int a, int b)
{
    long long ans = 0;
    a /= k;
    b /= k;
    if (a < b) std::swap(a, b);
    for (int i = 1, t; i <= b; i = t + 1)
    {
        t = std::min(a / (a / i), b / (b / i));
        ans += (long long)(mu[t] - mu[i - 1]) * (a / i) * (b / i);
    }
    return ans;
}

void run()
{
    init();
    int T = readIn();
    while (T--)
    {
        l1 = readIn();
        r1 = readIn();
        l2 = readIn();
        r2 = readIn();
        k = readIn();
        printOut(solve(r1, r2) - solve(l1 - 1, r2) - solve(r1, l2 - 1) + solve(l1 - 1, l2 - 1));
    }
}

int main()
{
    run();
    return 0;
}
发布了277 篇原创文章 · 获赞 21 · 访问量 6万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览