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

##### 简单容斥

像上一篇题解一样定义 $A\left(n,m\right)$$A(n, m)$，则答案为：

$A\left(b,d\right)-A\left(a,d\right)-A\left(b,c\right)+A\left(a,c\right)$

##### 参考代码
#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 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();
while (T--)
{
printOut(solve(r1, r2) - solve(l1 - 1, r2) - solve(r1, l2 - 1) + solve(l1 - 1, l2 - 1));
}
}

int main()
{
run();
return 0;
}

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