# 【bzoj2301】[HAOI2011]Problem b

## 2301: [HAOI2011]Problem b

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 5501  Solved: 2522
[Submit][Status][Discuss]

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

## Source

[Submit][Status][Discuss]

﻿

g(i) = ([b / i] - [(a - 1) / i]) * ([d / i] - [(c - 1) / i])

f[i] = Σμ(D) * g(D / i)        (d为i的倍数)

f[i] = Σμ(D) *  ([b / D] - [(a - 1) / D]) * ([d / D] - [(c - 1) / D])

= Σμ(D) *  ([b / D] * [d / D] - [(a - 1) / D] * [d / D] - [b / D] * [(c - 1) / D] + [(a - 1) / D] * [(c - 1) / D])

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<queue>
#include<stack>
using namespace std;

typedef long long LL;

const LL INF = 1000000000000000000LL;
const int maxn = 50100;

LL n,m,a,b,c,d,k,q;
LL sum[maxn],prime[maxn],tot,mu[maxn];
bool mark[maxn];

inline LL getint()
{
LL ret = 0,f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
ret = ret * 10 + c - '0',c = getchar();
return ret * f;
}

inline LL cal(LL n,LL m,LL k)
{
n /= k; m /= k;
LL last,ret = 0;
for (int i = 1; i <= min(n,m); i = last + 1)
{
last = min(n / (n / i),m / (m / i));
ret += (n / i) * (m / i) * (sum[last] - sum[i - 1]);
}
return ret;
}

int main()
{
mu[1] = 1;
for (int i = 2; i <= maxn; i++)
{
if (!mark[i])
{
mu[i] = -1;
prime[++tot] = i;
}
for (int j = 1; j <= tot; j++)
{
if (i * prime[j] > maxn) break;
mark[i * prime[j]] = 1;
if (i % prime[j]) mu[i * prime[j]] = -mu[i];
else
{
mu[i * prime[j]] = 0;
break;
}
}
}
for (int i = 1; i <= maxn; i++) sum[i] = sum[i - 1] + mu[i];
q = getint();
while (q--)
{
LL ans = 0;
a = getint(); b = getint(); c = getint(); d = getint(); k = getint();
printf("%lld\n",cal(b,d,k) - cal(a - 1,d,k) - cal(b,c - 1,k) + cal(a - 1,c - 1,k));
}
return 0;
}

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客