hdu 1695 容斥原理或莫比乌斯反演

GCD

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5310    Accepted Submission(s): 1907

Problem Description

Given 5 integers: a, b, c, d, k, you‘re to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you‘re only required to output the total number of different number pairs.
Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.

Yoiu can assume that a = c = 1 in all test cases.

Input

The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 cases.
Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.

Output

For each test case, print the number of choices. Use the format in the example.

Sample Input

2
1 3 1 5 1
1 11014 1 14409 9

Sample Output

Case 1: 9
Case 2: 736427

Hint

For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).

Source

2008 “Sunline Cup” National Invitational Contest

题目大意:求在1<=x<=b,1<=y<=d上gcd(x,y)=k的(x,y)对数

  1 /************容斥原理*************/
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <algorithm>
  6 using namespace std;
  7
  8 typedef __int64 LL;
  9 const int maxn=1e5+5;
 10 int phi[maxn],prime[maxn],factor[50],num;
 11 bool flag[maxn];
 12 void swap(int &a,int &b){ int t=a;a=b;b=t;}
 13
 14 void init()//欧拉筛选
 15 {
 16     memset(flag,true,sizeof(flag));
 17     phi[1]=1;
 18     for(int i=2;i<maxn;i++)
 19     {
 20         if(flag[i])
 21         {
 22             prime[num++]=i;
 23             phi[i]=i-1;
 24         }
 25         for(int j=0;j<num&&i*prime[j]<maxn;j++)
 26         {
 27             flag[i*prime[j]]=false;
 28             if(i%prime[j]==0)
 29             {
 30                 phi[i*prime[j]]=phi[i]*prime[j];
 31                 break;
 32             }
 33             else phi[i*prime[j]]=phi[i]*(prime[j]-1);
 34         }
 35     }
 36 }
 37
 38 void getfactor(int n,int &len)//质因数分解
 39 {
 40     int t=sqrt(n*1.0);len=0;
 41     for(int i=0;i<num&&prime[i]<=t;i++)
 42     {
 43         if(n%prime[i]==0)
 44         {
 45             factor[len++]=prime[i];
 46             while(n%prime[i]==0) n/=prime[i];
 47         }
 48     }
 49     if(n>1) factor[len++]=n;
 50 }
 51
 52 int getans(int a,int b)
 53 {
 54     int n;
 55     int ans=0;
 56     getfactor(b,n);
 57     for(int i=1;i<(1<<n);i++)//容斥原理
 58     {
 59         int cnt=0,temp=1;
 60         for(int j=0;j<n;j++)
 61         {
 62             if(i&(1<<j))
 63             {
 64                 cnt++;temp*=factor[j];
 65             }
 66         }
 67         if(cnt&1) ans+=a/temp;
 68         else ans-=a/temp;
 69     }
 70     return a-ans;
 71 }
 72
 73 int main()
 74 {
 75     int i,a,b,c,d,k,t,icase=0;
 76     LL ans;num=0;
 77     init();
 78     scanf("%d",&t);
 79     while(t--)
 80     {
 81         scanf("%d %d %d %d %d",&a,&b,&c,&d,&k);
 82         if(k==0||k>b||k>d)
 83         {
 84             printf("Case %d: 0\n",++icase);
 85             continue;
 86         }
 87         ans=0;
 88         b/=k;d/=k;
 89         if(b>d) swap(b,d);
 90         for(i=1;i<=b;i++) ans+=phi[i];
 91         for(i=b+1;i<=d;i++) ans+=getans(b,i);
 92         printf("Case %d: %I64d\n",++icase,ans);
 93     }
 94     return 0;
 95 }
 96 /*************莫比乌斯反演****************/
 97 #include <iostream>
 98 #include <cstdio>
 99 #include <cstring>
100 using namespace std;
101
102 typedef __int64 LL;
103 const int maxn=1e5+5;
104 int prime[maxn],mu[maxn],num;
105 bool flag[maxn];
106
107 void init()
108 {
109     memset(flag,true,sizeof(flag));
110     mu[1]=1;
111     for(int i=2;i<maxn;i++)
112     {
113         if(flag[i])
114         {
115             prime[num++]=i;mu[i]=-1;
116         }
117         for(int j=0;j<num&&i*prime[j]<maxn;j++)
118         {
119             flag[i*prime[j]]=false;
120             if(i%prime[j]==0)
121             {
122                 mu[i*prime[j]]=0;
123                 break;
124             }
125             else mu[i*prime[j]]=-mu[i];
126         }
127     }
128 }
129
130 int main()
131 {
132     num=0;
133     init();
134     int i,a,b,c,d,k,t,icase=0;
135     scanf("%d",&t);
136     while(t--)
137     {
138         scanf("%d %d %d %d %d",&a,&b,&c,&d,&k);
139         if(k==0||k>b||k>d)
140         {
141             printf("Case %d: 0\n",++icase);
142             continue;
143         }
144         b=b/k;d=d/k;
145         if(b>d) swap(b,d);
146         LL ans=0,ans1=0;
147         for(i=1;i<=b;i++)
148             ans+=(LL)mu[i]*(b/i)*(d/i);
149         for(i=1;i<=b;i++)
150             ans1+=(LL)mu[i]*(b/i)*(b/i);
151         ans-=ans1/2;
152         printf("Case %d: %I64d\n",++icase,ans);
153     }
154     return 0;
155 }

hdu 1695 容斥原理或莫比乌斯反演,布布扣,bubuko.com

时间: 2024-10-18 08:55:20

hdu 1695 容斥原理或莫比乌斯反演的相关文章

HDU 1695 GCD (莫比乌斯反演)

传送门 GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9749    Accepted Submission(s): 3648 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a-b, y in c-d that GCD(x, y)

HDU 1695 GCD 【莫比乌斯反演例题】

GCDTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4291 Accepted Submission(s): 1502   Problem DescriptionGiven 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k.

HDU 1695 GCD(莫比乌斯反演)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1695 [题目大意] 求出区间[1,b][1,d]中公约数为k的对数,重复的对数只计算一次. [题解] 我们将b和d调整成b<=d,题目转化为[1,b/k][1,d/k]中互质的数对数,由于重复的对数只计算一次,因此需要再计算一次[1,b/k][1,b/k],用原先答案减去计算出的一半就是答案. [代码] #include <cstdio> #include <algorithm&g

容斥原理与莫比乌斯反演的关系

//容斥原理,c[i]表示i当前要算的次数,复杂度和第二层循环相关 O(nlogn~n^2) LL in_exclusion(int n,int *c) { for(int i=0;i<=n;i++) c[i]=1; //不一定是这样初始化,要算到的才初始化为1 LL ans=0; for(int i=0;i<=n;i++) if(i要算) { ans+=(统计数)*c[i]; for(int j=i+1;j<=n;j++) if(i会算到j) c[j]-=c[i];//j要算的次数减去

hdu 1695 GCD(莫比乌斯入门)

题意:求a<=x<=b ,x<=y<=d,中gcd(x,y)==k的数对个数 思路:题目可以转化成求1<=x<=b/k,1<=y<=d/k中gcd(x,y)=1的数对的个数 我们设f(d)表示恰好gcd(x,y)==d的个数,F(d)表示gcd为d的倍数的数对个数 F(n)=∑d|nf(d)=> f(d)=∑d|nu(d)F(n/d) 令p=b/k q=d/k F(d)的计算十分简单 floor(p/d)*floor(q/d) 再利用线性筛法求莫比乌斯

2017多校第8场 HDU 6134 Battlestation Operational 莫比乌斯反演

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6134 题意: 解法: 那么g(n)怎么求,我们尝试打表发现g(n)是有规律的,g(n)=g(n-1)+d(n-1)+1,其中d(i)表示i的因子个数,这个我们是可以通过线性筛O(n)处理出来的,之后再O(n)维护g(i)的前缀和,就可以在单组sqrt(n)的复杂度下得到答案了. #include <bits/stdc++.h> using namespace std; typedef long l

HDU 6390 GuGuFishtion(莫比乌斯反演 + 欧拉函数性质 + 积性函数)题解

题意: 给定\(n,m,p\),求 \[ \sum_{a=1}^n\sum_{b=1}^m\frac{\varphi(ab)}{\varphi(a)\varphi(b)}\mod p \] 思路: 由欧拉函数性质可得:\(x,y\)互质则\(\varphi(xy)=\varphi(x)\varphi(y)\):\(p\)是质数则\(\varphi(p^a)=(p-1)^{a-1}\).因此,由上述两条性质,我们可以吧\(a,b\)质因数分解得到 \[ \begin{aligned} \sum_{

UVa 10214 (莫比乌斯反演 or 欧拉函数) Trees in a Wood.

题意: 这道题和POJ 3090很相似,求|x|≤a,|y|≤b 中站在原点可见的整点的个数K,所有的整点个数为N(除去原点),求K/N 分析: 坐标轴上有四个可见的点,因为每个象限可见的点数都是一样的,所以我们只要求出第一象限可见的点数然后×4+4,即是K. 可见的点满足gcd(x, y) = 1,于是将问题转化为x∈[1, a], y∈[1, b],求gcd(x, y) = 1的个数. 类比HDU 1695可以用莫比乌斯反演来做,我还写了普通的和分块加速的两份代码,交上去发现运行时间相差并不

hdu 1695 莫比乌斯反演

hdu 1695 莫比乌斯反演 题意: 给出a,b,c,d,k, 求满足a <= x <= b && c <= y <= d && gcd(x,y)=k 的数对(x,y)的对数. 限制: a=c=1; 0 < b,c <= 1e5; (n1,n2) 和 (n2,n1) 算为同种情况 思路: 其实是求满足1 <= x <= b/k && 1 <= y <= d/k && gcd(x,y