bzoj 2301 Problem b - 莫比乌斯反演
2017-07-24 22:19
260 查看
Description
对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。Input
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、kOutput
共n行,每行一个整数表示满足要求的数对(x,y)的个数Sample Input
22 5 1 5 1
1 5 1 5 2
Sample Output
143
HINT
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000题目大意 (如此简洁的题目就不需要我的烂文笔了)
这是在迎接codeforces div 2一场蓝(灰)之前恭迎的最后的一道水题(一个名为Doggu的数论神犇这么说的)。好了,废话不多说了。
如果你还没有做过bzoj 1101,那你应该赶紧做一下咯。
推理和它一毛一样,然后你发现它求的实际上等于一个二维前缀和,于是它便真地成了一道水题了(你基本上不用改动什么,copy过来,二维前缀和加加减减就水掉了)。
Code
/** * bzoj * Problem#2301 * Accepted * Time:14640ms * Memory:1576k */ #include <iostream> #include <cstdio> #include <ctime> #include <cmath> #include <cctype> #include <cstring> #include <cstdlib> #include <fstream> #include <sstream> #include <algorithm> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <list> #ifndef WIN32 #define Auto "%lld" #else #define Auto "%I64d" #endif using namespace std; typedef bool boolean; const signed int inf = (signed)((1u << 31) - 1); const signed long long llf = (signed long long)((1ull << 61) - 1); const double eps = 1e-6; const int binary_limit = 128; #define smin(a, b) a = min(a, b) #define smax(a, b) a = max(a, b) #define max3(a, b, c) max(a, max(b, c)) #define min3(a, b, c) min(a, min(b, c)) template<typename T> inline boolean readInteger(T& u){ char x; int aFlag = 1; while(!isdigit((x = getchar())) && x != '-' && x != -1); if(x == -1) { ungetc(x, stdin); return false; } if(x == '-'){ x = getchar(); aFlag = -1; } for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0'); ungetc(x, stdin); u *= aFlag; return true; } const int limit = 5e4; int n; int num = 0; int prime[10000]; int miu[limit + 1]; boolean vis[limit + 1]; inline void Euler() { memset(vis, false, sizeof(vis)); miu[0] = 0, miu[1] = 1; for(int i = 2; i <= limit; i++) { if(!vis[i]) miu[i] = -1, prime[num++] = i; for(int j = 0; j < num && prime[j] * 1LL * i <= limit; j++) { int c = prime[j] * i; vis[c] = true; if((i % prime[j]) == 0) { miu[c] = 0; break; } else { miu[c] = -1 * miu[i]; } } miu[i] += miu[i - 1]; } } inline void init() { readInteger(n); } inline long long calc(int a, int b, int d) { long long ret = 0; a /= d, b /= d; if(a == 0 || b == 0) return 0; if(a > b) swap(a, b); ret = 0; for(int i = 1, j; i <= a; i = j + 1) { j = min(a / (a / i), b / (b / i)); ret += (a / j) * 1LL * (b / j) * (miu[j] - miu[i - 1]); } return ret; } inline void solve() { int a, b, c, d, e; while(n--) { scanf("%d%d%d%d%d", &a, &b, &c, &d, &e); printf(Auto"\n", calc(b, d, e) - calc(a - 1, d, e) - calc(c - 1, b, e) + calc(a - 1, c - 1, e)); } } int main() { Euler(); init(); solve(); return 0; }
相关文章推荐
- [BZOJ1101&BZOJ2301][POI2007]Zap [HAOI2011]Problem b|莫比乌斯反演
- 【BZOJ2301】【HAOI2011】Problem b 莫比乌斯反演
- bzoj2301 [HAOI2011]Problem b 莫比乌斯反演
- Bzoj 2301: [HAOI2011]Problem b(莫比乌斯反演+除法分块)
- BZOJ 2301 Problem b (莫比乌斯反演)
- bzoj 2301: [HAOI2011]Problem b(莫比乌斯反演)
- BZOJ2301 [HAOI2011]Problem b(莫比乌斯反演)
- BZOJ 2301: [HAOI2011]Problem b(莫比乌斯反演)
- BZOJ 2301 [HAOI2011]Problem b (莫比乌斯反演)
- BZOJ 2301: [HAOI2011]Problem b(莫比乌斯反演 + 容斥原理 + 分块优化)
- 莫比乌斯反演(bzoj 2301: [HAOI2011]Problem b)
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- BZOJ 2301 Problem b(莫比乌斯反演)
- 【bzoj2301】[HAOI2011]Problem b 莫比乌斯反演
- bzoj 2301 [HAOI2011]Problem b(莫比乌斯反演)
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- BZOJ 2301 Problem b (莫比乌斯反演)
- BZOJ 2301 [HAOI2011]Problem b (分块 + 莫比乌斯反演)
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- BZOJ 2301 Problem b (莫比乌斯反演+区间容斥+分块)