# 【莫比乌斯】 BZOJ 2301 Problem b

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c = getchar() , c == EOF) return false;
while(c != '-' && (c < '0' || c > '9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return true;
}

const int MAX_N = 50007;

int pcnt, prime[MAX_N], mu[MAX_N];
bool vis[MAX_N];

void Mobius(int n) {
pcnt = 0;
vis[1] = mu[1] = 1;
for(int i = 2;i <= n; i++) {
if(!vis[i]) prime[pcnt++] = i, mu[i] = -1;
for (int j = 0; j < pcnt && prime[j] * i <= n; ++j) {
vis[prime[j] * i] = true;
if (i % prime[j] == 0) {
mu[i * prime[j]] = 0;
break;
} else mu[i * prime[j]] = -mu[i];
}
}
}

int a, b, c, d, k;
int s[MAX_N];

ll cal(int l, int r) {
l /= k, r /= k;
int n = min(l, r);
ll ans = 0;
for (int i = 1, j = 0; i <= n; i = j + 1) {
j = min(l / (l / i), r / (r / i));
ans += ((ll)s[j] - s[i - 1]) * (l / i) * (r / i);
}
return ans;
}

int main() {
Mobius(MAX_N - 2);
for (int i = 1; i < MAX_N; ++i) s[i] = s[i - 1] + mu[i];
int T; rd(T);
while (T-- > 0) {
rd(a), rd(b), rd(c), rd(d), rd(k);
ll ans = cal(b, d) - cal(a - 1, d) - cal(b, c - 1) + cal(a - 1, c- 1);
printf("%lld\n", ans);
}
return 0;
}
View Code

posted @ 2015-08-17 21:42  Rojo ゛  阅读(...)  评论(...编辑  收藏