# BZOJ 2301: [HAOI2011]Problem b（莫比乌斯反演 + 容斥原理 + 分块优化）

Problem 2301. – [HAOI2011]Problem b

## 2301: [HAOI2011]Problem b

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 3671  Solved: 1643
[Submit][Status][Discuss]

## Output

n行，每行一个整数表示满足要求的数对(x,y)的个数

2

2 5 1 5 1

1 5 1 5 2

14

3

## HINT

100%的数据满足：1≤n≤50000，1≤a≤b≤50000，1≤c≤d≤50000，1≤k≤50000

1xN,1yM$1 \leq x \leq N,1 \leq y \leq M$ 而且 GCD(x,y)==k$GCD(x,y)==k$,这个题目可以和上次一样转化为有

GCD(x,y)=1$GCD(x,y)=1$,然后令 f(i)$f(i)$1xN,1yM,GCD(x,y)==1$1\leq x\leq N,1\leq y\leq M,而且 GCD(x,y)==1$

F(i)=floor(ni)floor(mi)

f(i)=i|dmu(di)F(d)=i|dmu(di)floor(nd)floor(md)

/**
2016 - 08 - 17 晚上
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 = 1e5+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');
}
LL mu[MAXN], p[MAXN], k;
bool prime[MAXN];
void Mobius()
{
memset(prime, 0, sizeof(prime));
mu[1] = 1, mu[0] = 0;
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];
}
}
for(int i=1; i<MAXN; i++)
mu[i] += mu[i-1];
}
int kk;
LL Solve(int m, int n)
{
LL ret = 0;
m /= kk, n /= kk;
int tp = 0;
for(int i=1; i<=m&&i<=n; i=tp+1)
{
tp = min(n/(n/i),m/(m/i));
ret += (mu[tp]-mu[i-1])*(m/i)*(n/i);
}
return ret;
}
int main()
{
Mobius();
int T, a, b, c, d;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d%d",&a,&b,&c,&d,&kk);
LL ans = Solve(b, d) - Solve(a-1, d) + Solve(a-1, c-1) - Solve(b, c-1);
printf("%lld\n",ans);
}
return 0;
}

©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客