bzoj 2301: [HAOI2011]Problem b(莫比乌斯反演)
2017-08-08 10:07
387 查看
入门题,https://wenku.baidu.com/view/fbe263d384254b35eefd34eb.html,链接中讲的和这个题差不多,讲得挺好
http://blog.csdn.net/acdreamers/article/details/8542292这里面第二个例题和本题也差不多,讲得挺好
朋友写的题解:https://www.dreamwings.cn/bzoj2301/4853.html
题目要求是:每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,可以转化为
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/f1efcd44be021700c5ef2acd66827040)
,
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/a0dcb895dd93b01aec6148653c097c5f)
,gcd(x,y) = 1,求有多少对这样的(x,y),(2,3),(3,2)算两对
设f(i)为1<=x<=n,1<=y<=m,且gcd(x,y) = i的(x,y)的对数,设F(i)为满足i|gcd(x,y)的(x,y)的对数,即gcd(x,y)是i的整数倍的(x,y)的对数
先放公式:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/afd7f41ca7b9364736a1d25cf424cd4c)
显然:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/9acb2723bfa3a24120a4898bce444462)
则
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/d22168e3e384922cd786f32e80b4c544)
代码里有分块优化,就是:
就是指在连续的某段,比如10/6=10/7=10/8=10/9=10/10=1,这一段除以5的值相同,就可以求出来莫比乌斯函数的前缀和,提取公因式,合并到一块。
这段区间下届是6,上届是10/(10/6),即10
从我写的公式里来看分块优化这段代码,显得很别扭,这里有一个分析详细的:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/851c59817faef23929e42316fa7a67a3)
图片截取自:http://www.cnblogs.com/candy99/p/6209502.html
http://blog.csdn.net/acdreamers/article/details/8542292这里面第二个例题和本题也差不多,讲得挺好
朋友写的题解:https://www.dreamwings.cn/bzoj2301/4853.html
题目要求是:每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,可以转化为
,
,gcd(x,y) = 1,求有多少对这样的(x,y),(2,3),(3,2)算两对
设f(i)为1<=x<=n,1<=y<=m,且gcd(x,y) = i的(x,y)的对数,设F(i)为满足i|gcd(x,y)的(x,y)的对数,即gcd(x,y)是i的整数倍的(x,y)的对数
先放公式:
显然:
则
代码里有分块优化,就是:
ans += (LL)(sum[la]-sum[i-1])*(n/i)*(m/i);
就是指在连续的某段,比如10/6=10/7=10/8=10/9=10/10=1,这一段除以5的值相同,就可以求出来莫比乌斯函数的前缀和,提取公因式,合并到一块。
这段区间下届是6,上届是10/(10/6),即10
从我写的公式里来看分块优化这段代码,显得很别扭,这里有一个分析详细的:
图片截取自:http://www.cnblogs.com/candy99/p/6209502.html
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 100000; bool check[MAXN+10]; int prime[MAXN+10]; int mu[MAXN+10]; int a,b,c,d,k,n; void Moblus() { memset(check,false,sizeof(check)); mu[1] = 1; int tot = 0; for(int i = 2; i <= MAXN; ++i) { if(!check[i]) { prime[tot++] = i; mu[i] = -1; } for(int j = 0; j < tot; ++j) { if(i*prime[j] > MAXN) break; check[i*prime[j]] = true; if(i%prime[j] == 0) { mu[i*prime[j]] = 0; break; } else { mu[i*prime[j]] = -mu[i]; } } } } int sum[MAXN+10]; LL solve(int n, int m) { LL ans = 0; if(n > m) swap(n,m); for(int i = 1, la = 0; i <= n; i = la+1) { la = min(n/(n/i),m/(m/i)); ans += (LL)(sum[la]-sum[i-1])*(n/i)*(m/i); } return ans; } int main() { Moblus(); for(int i = 1; i <= MAXN; ++i) sum[i] = sum[i-1] + mu[i]; scanf("%d",&n); while(n--) { scanf("%d %d %d %d %d",&a,&b,&c,&d,&k); LL ans = solve(b/k,d/k) - solve((a-1)/k,d/k) - solve(b/k,(c-1)/k) + solve((a-1)/k,(c-1)/k); printf("%d\n",ans); } return 0; }
相关文章推荐
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- BZOJ.2301.[HAOI2011]Problem B(莫比乌斯反演 容斥)
- 【BZOJ2301】【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(莫比乌斯反演,分块,容斥)
- BZOJ 2301: [HAOI2011]Problem b (莫比乌斯反演)
- Bzoj 2301: [HAOI2011]Problem b(莫比乌斯反演+除法分块)
- BZOJ 2301 [HAOI2011]Problem b (莫比乌斯反演)
- [bzoj2301] [HAOI2011]Problem b(莫比乌斯反演)
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- [BZOJ 2301][HAOI2011] Problem b 莫比乌斯反演
- BZOJ 2301: [HAOI2011]Problem b(莫比乌斯反演 + 容斥原理 + 分块优化)
- BZOJ 2301: [HAOI2011]Problem b(莫比乌斯反演)
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- [BZOJ1101&BZOJ2301][POI2007]Zap [HAOI2011]Problem b|莫比乌斯反演
- 【HAOI2011】【BZOJ2301】Problem b(莫比乌斯反演,容斥原理)
- BZOJ 2301 [HAOI2011]Problem b (莫比乌斯反演)