hdu 1695 GCD (欧拉函数+容斥原理+素因子分解)
来源:互联网 发布:杭州和盈培训java学费 编辑:程序博客网 时间:2024/05/21 16:56
hdu 1695 GCD (欧拉函数+容斥原理+素因子分解) :http://acm.hdu.edu.cn/showproblem.php?pid=1695
题面描述:
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8787 Accepted Submission(s): 3261
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.
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.
21 3 1 5 11 11014 1 14409 9
Case 1: 9Case 2: 736427HintFor 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).
题目大意:
在x区间[a,b]和y区间[c,d]中出满足gcd(x,y)=k的(x,y)的对数。
题目分析:
数据不是暴力就能过的,需要用到莫比乌斯反演的思想,具体分析如下:
(1)由于gcd(x,y)=k满足gcd(x/k,y/k)=1,所以区间可以缩小为:[1/k.b/k],[1/k,d/k],问题也转化成为取两区间中的元素x,y,使得gcd(x,y)=1;
(2)由于gcd(y,x)=1和gcd(x,y)=1是相同的,假设x<y,于是可以先取小区间进行讨论,由于gcd(x,y)=1,利用欧拉函数,所以小区间可以计算为:
ans+=phi[1]+phi[2]+...+phi[b](用欧拉函数的递推形式保存起来即可);
(3)对于[b/k+1,d/k],设y为区间的一个元素,则可以对y进行素因子分解,于是得到集合:[p1,p2,p3,...],其中pi为素数,虽然是要求gcd(x,y)=1的组合,但反过来也可以求gcd(x,y)!=1的组合,于是可以用容斥原理进行统计能被这些素数整除的数的个数,最后相减求补数即可加到ans.
代码实现:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#define Maxn 100001using namespace std;int noprime[10000],no;int t,a,b,c,d,k,sum,casenum;void dfs(int i,int nu,int x,int mu) //容斥原理一般和递归一起用{ if(nu==x) { sum+=b/mu; return; } if(i==no) return; dfs(i+1,nu+1,x,mu*noprime[i]); dfs(i+1,nu,x,mu); return;}int rong() //容斥定理{ int s=0; for(int i=1; i<=no; i++) { sum=0; dfs(0,0,i,1); if(i&1) s+=sum;//奇数加,偶数减 else s-=sum; } return b-s;//求的是互质的,取反}int main(){ int phi[Maxn],prime[10000];//欧拉函数的递推形式 bool boo[Maxn]; for(int i=1; i<Maxn; i++) phi[i]=i; for(int i=2; i<Maxn; i+=2) phi[i]/=2; for(int i=3; i<Maxn; i+=2) { if(phi[i]==i) { for(int j=i; j<Maxn; j+=i) { phi[j]=phi[j]/i*(i-1); } } } memset(boo,0,sizeof(boo));//线性筛素数 boo[0]=boo[1]=1; int p=0; for(int i=2; i<Maxn; i++) { if(!boo[i]) prime[p++]=i; for(int j=0; j<p&&i*prime[j]<Maxn; j++) { boo[i*prime[j]]=1; if(!(i%prime[j])) break; } } casenum=0; scanf("%d",&t); while(t--) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k==0) //注意k等于0的情况 { printf("Case %d: 0\n",++casenum); continue; } b/=k; d/=k; if(b>d) { int w=b; b=d; d=w; } long long ans=0; for(int i=1; i<=b; i++) { ans+=phi[i]; } for(int i=b+1; i<=d; i++) { no=0; int aa=i; for(int j=0; j<p&&prime[j]*prime[j]<=aa; j++) if(!(aa%prime[j])) { noprime[no++]=prime[j]; aa/=prime[j]; while(aa%prime[j]==0) { aa/=prime[j]; }// do// aa/=prime[j];// while(aa%prime[j]==0); } if(aa>1) { noprime[no++]=aa; } ans+=rong(); } printf("Case %d: %lld\n",++casenum,ans); } return 0;}
- HDU 1695 GCD(素因子分解+容斥原理+欧拉函数)
- hdu 1695 GCD (欧拉函数+容斥原理+素因子分解)
- hdu GCD 【欧拉函数,素因子分解,筛选法,容斥原理】
- HDU 1695 GCD 【容斥】【质因数分解】【欧拉函数】
- HDU 1695 GCD 欧拉函数+容斥原理+质因数分解
- HDU/HDOJ 1695 GCD 欧拉函数+容斥原理
- HDU 1695 GCD 欧拉函数+容斥原理
- hdu 1695 GCD 欧拉函数+容斥原理
- HDU 1695 GCD(欧拉函数+容斥原理)
- hdu 1695 GCD(容斥原理+欧拉函数)
- hdu 1695 GCD(欧拉函数+容斥原理)
- 【HDU】1695 GCD 欧拉函数+容斥原理
- hdu 1695 GCD 欧拉函数+容斥原理
- hdu 1695 GCD(容斥原理+欧拉phi函数)
- HDU 1695 GCD(欧拉函数+容斥原理)
- hdu 1695 GCD【欧拉函数+容斥原理】
- hdu-1695 GCD(容斥原理+欧拉函数)
- hdu 1695 GCD (欧拉函数、容斥原理)
- 国内外 Android 技术大牛 入口
- C 【数据类型 静态&动态】
- maven导入本地jar文件
- 图解VC++ opengl环境配置和几个入门例子
- POJ1797 Heavy Transportation
- hdu 1695 GCD (欧拉函数+容斥原理+素因子分解)
- 《算法导论》学习摘要chapter-6——优先队列
- POJ_3253_Fence Repair
- hdoj Lining Up 1432 (数学)直线过最多点问题
- Spring MVC 常用的那些注解
- ife-task3:三栏式布局--再谈position 属性的基本知识
- April Fools Day Contest 2016 题解
- Step by Step into Spring(IOC)
- 前端需要了解的