题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695

题目是求 在区间[a,b]选一个数x,区间[c,d]选一个数y,求满足gcd(x,y) = k 的个数

题目给出了条件,可以认为所有的样例中,a = b = 1,那么就是在区间[1,b]和区间[1,d]中分别选择两个数求gcd(x,y) = k的个数

我们让区间[1,b]和[1,d]变为[1,b/k]和[1,d/k],这里就可以转化为求gcd(x,y) = 1的个数

我们假设  f 是gcd(x,y) = n的个数,F 是gcd(x,y) = n的倍数的个数

显然 F 和 f  存在如下倍数关系,即:

设b/k = m,d/k = n,若要求gcd(x,y) =  z 的倍数的个数,那么则F(z) 显然为  (m/z)*(n/z)

由莫比乌斯反演得:

莫比乌斯函数:

其中莫比乌斯函数的线性筛模板如下:

  1. ll prime[maxn],mu[maxn],vis[maxn],F[maxn];
  2. void get_mu() { //莫比乌斯函数线性筛
  3. int N = maxn;
  4. memset(prime,0,sizeof(prime));
  5. memset(mu,0,sizeof(mu));
  6. memset(vis,0,sizeof(vis));
  7. mu[1] = 1;
  8. int cnt = 0;
  9. for(int i = 2;i<N;i++){
  10. if(!vis[i]){
  11. prime[cnt++] = i;
  12. mu[i] = -1;
  13. }
  14. for(int j = 0;j<cnt && i*prime[j]<N;j++){
  15. vis[i*prime[j]] = 1;
  16. if(i%prime[j]) mu[i*prime[j]] = -mu[i];
  17. else{
  18. mu[i*prime[j]] = 0;
  19. break;
  20. }
  21. }
  22. }
  23. }

题目转化为在区间[1,b/k]和[1,d/k]中求gcd(x,y) = 1的对数,其实就是求f(1)了,直接计算f (1)。

因为题目要求如(2,1)和(1,2)是相同的实数对,所以要去重,而重复部分是在f(1)求解过程中的u(1)*F(1) + u(2)*F(2) + u(3)*F(3) + ........+u(min(m,n))*F(min(m,n)),这部分答案除以2是重复累加的,最后再计算一遍减去即可。

AC代码:

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #define maxn 100005
  6. using namespace std;
  7. typedef long long ll;
  8. const int INF = 1 << 30;
  9. const int MOD = 1e9 + 7;
  10. ll prime[maxn],mu[maxn],vis[maxn],F[maxn];
  11. void get_mu() { //莫比乌斯函数线性筛
  12. int N = maxn;
  13. memset(prime,0,sizeof(prime));
  14. memset(mu,0,sizeof(mu));
  15. memset(vis,0,sizeof(vis));
  16. mu[1] = 1;
  17. int cnt = 0;
  18. for(int i = 2;i<N;i++){
  19. if(!vis[i]){
  20. prime[cnt++] = i;
  21. mu[i] = -1;
  22. }
  23. for(int j = 0;j<cnt && i*prime[j]<N;j++){
  24. vis[i*prime[j]] = 1;
  25. if(i%prime[j]) mu[i*prime[j]] = -mu[i];
  26. else{
  27. mu[i*prime[j]] = 0;
  28. break;
  29. }
  30. }
  31. }
  32. }
  33. int main(){
  34. int t;
  35. ios::sync_with_stdio(false);
  36. cin>>t;
  37. int cnt = 1;
  38. get_mu();
  39. while(t--){
  40. cout<<"Case "<<cnt<<": ";
  41. cnt++;
  42. int a,b,c,d,k;
  43. cin>>a>>b>>c>>d>>k;
  44. if (k == 0) {
  45. cout<<0<<endl;
  46. continue;
  47. }
  48. b/=k,d/=k;
  49. ll ans = 0,t = 0;
  50. for(int i= 1;i<=min(b,d);i++){
  51. ans+=(long long)mu[i]*(b/i)*(d/i);
  52. }
  53. for(int i = 1;i<=min(b,d);i++){
  54. t+=(long long)mu[i]*(min(b,d)/i)*(min(b,d)/i);//计算重复部分
  55. }
  56. cout<<ans-t/2<<endl;
  57. }
  58. }

hdu1695(莫比乌斯反演+容斥)的更多相关文章

  1. BZOJ.2301.[HAOI2011]Problem B(莫比乌斯反演 容斥)

    [Update] 我好像现在都看不懂我当时在写什么了=-= \(Description\) 求\(\sum_{i=a}^b\sum_{j=c}^d[(i,j)=k]\) \(Solution\) 首先 ...

  2. BZOJ 2301 Problem b (莫比乌斯反演+容斥)

    这道题和 HDU-1695不同的是,a,c不一定是1了.还是莫比乌斯的套路,加上容斥求结果. 设\(F(n,m,k)\)为满足\(gcd(i,j)=k(1\leq i\leq n,1\leq j\le ...

  3. 洛谷P2522 [HAOI2011]Problem b (莫比乌斯反演+容斥)

    题意:求$\sum_{i=a}^{b}\sum_{j=c}^{d}[gcd(i,j)==k]$(1<=a,b,c,d,k<=50000). 是洛谷P3455 [POI2007]ZAP-Qu ...

  4. BZOJ2301:[HAOI2011]Problem b(莫比乌斯反演,容斥)

    Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...

  5. 2301: [HAOI2011]Problem b ( 分块+莫比乌斯反演+容斥)

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 6015  Solved: 2741[Submit] ...

  6. 【莫比乌斯反演+容斥】BZOJ2301-[HAOI2011]Problem b(成为权限狗的第一题纪念!)

    [题目大意] 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. [思路] “怎么又是你系列……”思路 ...

  7. HDU 6053 TrickGCD 莫比乌斯函数/容斥/筛法

    题意:给出n个数$a[i]$,每个数可以变成不大于它的数,现问所有数的gcd大于1的方案数.其中$(n,a[i]<=1e5)$ 思路:鉴于a[i]不大,可以想到枚举gcd的值.考虑一个$gcd( ...

  8. bzoj2440 完全平方数 莫比乌斯值+容斥+二分

    莫比乌斯值+容斥+二分 /** 题目:bzoj2440 完全平方数 链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2440 题意:求第k个小x数 ...

  9. BZOJ 2440 莫比乌斯函数+容斥+二分

    2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5473  Solved: 2679[Submit][Sta ...

随机推荐

  1. 记一个js toUpperCase函数 大小写特性

    toUpperCase()是javascript中小写变大写的函数 "ı".toUpperCase() == 'I',"ſ".toUpperCase() == ...

  2. C#使用OracleBulkCopy

    首先使用PL/SQL  通过语句:select * from v$version; 查询出使用的oracle版本,弄到对应版本的Oracle.DataAccess.DLL 我本地使用版本为:11.2. ...

  3. Java知识串讲

    一.JDK个版本之间的区别: 1.JDK1.5的新特性: 泛型ArrayList list = new ArrayList();-->ArrayList<int> list = ne ...

  4. CSS 实现一个自适应的正方形

      传统方法正方形用固定的形式写 直接长=宽写固定的值如下   .box{   width: 200px;   height: 200px;   background: pink;   color: ...

  5. 【Unity|C#】基础篇(16)——文件读写(I/O类)

    [笔记] 文件操作 File / FileInfo / FileStream https://www.runoob.com/csharp/csharp-file-io.html 文本读写 Stream ...

  6. MongoDB一些应用知识点

    1.在生产环境中至少需要三个节点的复制集架构. 2.在多数的场景中WT引擎比MMAPv1更加出色. 3.要想达到极致的速度,那么一定要给MongoDB足够的内存. 4.避免使用短链接,充分利用连接池, ...

  7. CTF之图片隐写术解题思路

    参考大佬的博客:https://blog.csdn.net/a_small_rabbit/article/details/79644078 深有感触,觉得写得比较全,因此将此篇文章记录在此方便以后用得 ...

  8. oracle sql 数据库之间导入数据

    1.导入别的表 insert into EMPI_IDENTIFY select id,empiid, name||':' ||idcardno,'accidcardno','' from empi_ ...

  9. 在vue中使用elementUI饿了么框架使用el-tabs,切换Tab如何实现实时加载,以及el-table表格使用总结

    当我们在开发中遇到tab切换,这时候用el的el-tabs感觉很方便 但当我在把代码都写完后,发现一个问题就是页面打开时 虽然我们只能看见当前一个tab页,但是vue会帮你把你写的所有tab页的内容都 ...

  10. [CF]Round514

    A Cashier 题意:一个人,一天的工作时长为\(L\),从第\(t_i\)时刻开始有长度为\(l_i\)的工作,他想在工作间隙抽烟,抽一根要\(a\)分钟,问能抽几根. 直接模拟. B Forg ...