HDU1695 GCD 【欧拉函数】【容斥原理】
2017-12-07 21:12
393 查看
最近看了很多容斥原理的题目,跟离散上学的不大一样了,有时候根本想不到,有些题目看了题解都不懂,凡是牵扯到位运算的我感觉都不简单。。。
题意:求x∈[1,b]和y∈[1,d]的区间内有多少组gcd(x,y)==k,其中(x,y)(y,x)算是一组
思路:先做一个小变换,b,d都除以k,问题变为求x∈[1,b/k]和y∈[1,d/k]的区间内有多少组gcd(x,y)==1
在此基础上,令b=b/k,d=d/k,假设b<d,对于<b的部分,很明显可以用欧拉函数直接求出
对于[b+1,d]的部分,主要思想就是,首先把每个数据做因子分解,求出与其不互质的数据个数,b减去即可
这里就用到了容斥原理,Goal=可以被一个因子整除的个数-可以被两个因子整除的个数+可以被三个因子整除的个数(-1)^(n+1)(整除n个的个数)
假设x=6,因子为2,3,区间为[1,15],map[1|2]={2,4,6,8,10,12,14,}map[1|3]={3,6,9,12,15} map[2|2,3]={6,12}
Goal=7+5-2=10 所以与6互质的有5个
如果p(p!=1)是x的因子,那么在区间[1,d]中,有d/p个数与x不互质
假设x有num个因子,1除外,根据组合数学的公式C1+C2+……=2^num,枚举各类情况
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.
InputThe input consists of several test cases. The first line of the input is the number
4000
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.
OutputFor each test case, print the number of choices. Use the format in the example.
Sample Input
题意:求x∈[1,b]和y∈[1,d]的区间内有多少组gcd(x,y)==k,其中(x,y)(y,x)算是一组
思路:先做一个小变换,b,d都除以k,问题变为求x∈[1,b/k]和y∈[1,d/k]的区间内有多少组gcd(x,y)==1
在此基础上,令b=b/k,d=d/k,假设b<d,对于<b的部分,很明显可以用欧拉函数直接求出
对于[b+1,d]的部分,主要思想就是,首先把每个数据做因子分解,求出与其不互质的数据个数,b减去即可
这里就用到了容斥原理,Goal=可以被一个因子整除的个数-可以被两个因子整除的个数+可以被三个因子整除的个数(-1)^(n+1)(整除n个的个数)
假设x=6,因子为2,3,区间为[1,15],map[1|2]={2,4,6,8,10,12,14,}map[1|3]={3,6,9,12,15} map[2|2,3]={6,12}
Goal=7+5-2=10 所以与6互质的有5个
如果p(p!=1)是x的因子,那么在区间[1,d]中,有d/p个数与x不互质
假设x有num个因子,1除外,根据组合数学的公式C1+C2+……=2^num,枚举各类情况
GCD
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.
InputThe input consists of several test cases. The first line of the input is the number
4000
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.
OutputFor 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 9Sample Output
Case 1: 9 Case 2: 736427
#include<iostream> #include<stdio.h> #include<string.h> #include<cmath> #include<algorithm> using namespace std; #define ll long long #define MOD 1000000007 #define N 100010 int a,b,c,d,gg; int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } int lcm(int a, int b) { return a/gcd(a, b)*b; } int prime ,vis ; int phi ; void init() { int i; for(i=2;i<=100000;i++) phi[i]=0; phi[1]=1; for(i=2;i<=100000;i++) if(!phi[i]) for(int j=i;j<=100000;j+=i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); } } int k; void Oula(int n) { k=0; for(int i=2;i<n;i++) { if(!vis[i]) prime[k++]=i; for(int j=0;j<k&&i*prime[j]<n;j++) { vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int num; int p ; void fun(int kk, int &ans) { ans = 1; int i; int cnt = 0; for (i = 0; i < num&& kk > 0; kk >>= 1, i++) { if (kk & 1) { ans = lcm(ans, p[i]); cnt++; } } if (!(cnt & 1)) ans = -ans; } int cal(int n) { num=0; for(int i=0;i<k&&prime[i]*prime[i]<=n;i++) { if(n%prime[i]==0) { p[num++]=prime[i]; while(n%prime[i]==0) n/=prime[i]; } } if(n!=1) p[num++]=n; int sum = 0; int tmp; for (int i=1;i<(1<<num);i++) { fun(i,tmp); tmp=b/tmp; sum+=tmp; } return b-sum; } int main() { init(); Oula(N); int n; int t; cin>>t; for(int cas=1;cas<=t;cas++) { ll ans=0; scanf("%d%d%d%d%d",&a,&b,&c,&d,&gg); cout<<"Case "<<cas<<": "; if(gg==0) cout<<0<<endl; else { b/=gg; d/=gg; if(b>d) { int temp=b; b=d; d=temp; } for(int i=1;i<=b;i++) ans+=phi[i]; for(int i=b+1;i<=d;i++) ans+=cal(i); cout<<ans<<endl; } } return 0; }
相关文章推荐
- HDU1695 GCD 欧拉函数+容斥原理
- HDU1695:GCD(容斥原理+欧拉函数+质因数分解)好题
- hdu1695 GCD (容斥原理+欧拉函数)
- HDU 1695 GCD(素因子分解+容斥原理+欧拉函数)
- hdu1695 GCD2 容斥原理 求x属于[1,b]与y属于[1,d],gcd(x,y)=k的对数。(5,7)与(7,5)看作同一对。
- ACM学习历程—HDU1695 GCD(容斥原理 || 莫比乌斯)
- HDU 1695 GCD 解题报告(欧拉函数 + 容斥原理)
- HDU 1695 GCD ★(容斥原理+欧拉函数)
- HDU 1695 GCD ★(容斥原理+欧拉函数)
- HDU 1695 GCD (欧拉函数,容斥原理)
- GCD HDU - 1695 容斥原理+欧拉函数打表
- HDU 1695 GCD (欧拉函数,容斥原理)
- HDU 1695-GCD(容斥原理+欧拉函数)
- hdu GCD 【欧拉函数,素因子分解,筛选法,容斥原理】
- hdu 1695 GCD (欧拉函数、容斥原理)
- HDU1695 GCD(容斥原理)
- GCD Again HDU - 1787 (欧拉函数 or 容斥原理)
- hdu 1695 GCD (素数筛选 + 欧拉函数 + 容斥原理)
- hdu 1695 GCD(容斥原理+欧拉函数)
- HDU1695素数打表欧拉函数容斥原理(再看)