4712 gcd与lcm问题
2016-10-18 14:32
176 查看
题目描述 Description
【NOIP2001最大公约数和最小公倍数问题】的加强版。
T组数据,每组数据给出d,m,求满足gcd(i, j)=d且lcm(i, j)=m的(i, j)的个数。
输入描述 Input Description
第1行是一个数T,表示数据组数。
接下来的T行,每行两个数d,m,意义见题目描述。
输出描述 Output Description
输出应有T行,每行一个整数,表示该问题的答案。
样例输入 Sample Input
1
3 60
样例输出 Sample Output
4
提示:这4个(i, j)分别是(3, 60),(12, 15),(15, 12),(60, 3)。
数据范围及提示 Data Size & Hint
对于10%的数据,T=1,d=3,m=60;
对于50%的数据,T=1,d≤1000000,m≤1000000;
对于100%的数据,T≤100000,d≤1000000,m≤1000000。
注意判断数据是否合法,存在d=0或m=0的情况。
这个题因为数据范围比较大,所以不可能单个的去枚举,所以我们要根据最大公因数的最小公倍数的性质来进行质因数分解。
我们知道最大公因数的每一个因子的幂是两个数幂的较小的,而最大公倍数则是大的。
比如说:15=20*31*51
12=22*31*50
gcd(15,12)=2min(0,2)*3min(1,1)*5min(0,1)=20*31*50=3
lcm(15,12)=2max(0,2)*3max(1,1)*5max(0,1)=22*31*51=60
我们假设a,b的为gcd,lcm的解。
所以我们对gcd和lcm进行拆分,若两个数同一个因子的两个幂相等,那么这个因子
就不需要考虑,如果不一样那么说明这个幂可能放在a上,也可能在b上,那么这就
需要注意:若题目给出的gcd,lcm都等于0或者互质那么答案一定是0;
【NOIP2001最大公约数和最小公倍数问题】的加强版。
T组数据,每组数据给出d,m,求满足gcd(i, j)=d且lcm(i, j)=m的(i, j)的个数。
输入描述 Input Description
第1行是一个数T,表示数据组数。
接下来的T行,每行两个数d,m,意义见题目描述。
输出描述 Output Description
输出应有T行,每行一个整数,表示该问题的答案。
样例输入 Sample Input
1
3 60
样例输出 Sample Output
4
提示:这4个(i, j)分别是(3, 60),(12, 15),(15, 12),(60, 3)。
数据范围及提示 Data Size & Hint
对于10%的数据,T=1,d=3,m=60;
对于50%的数据,T=1,d≤1000000,m≤1000000;
对于100%的数据,T≤100000,d≤1000000,m≤1000000。
注意判断数据是否合法,存在d=0或m=0的情况。
这个题因为数据范围比较大,所以不可能单个的去枚举,所以我们要根据最大公因数的最小公倍数的性质来进行质因数分解。
我们知道最大公因数的每一个因子的幂是两个数幂的较小的,而最大公倍数则是大的。
比如说:15=20*31*51
12=22*31*50
gcd(15,12)=2min(0,2)*3min(1,1)*5min(0,1)=20*31*50=3
lcm(15,12)=2max(0,2)*3max(1,1)*5max(0,1)=22*31*51=60
我们假设a,b的为gcd,lcm的解。
所以我们对gcd和lcm进行拆分,若两个数同一个因子的两个幂相等,那么这个因子
就不需要考虑,如果不一样那么说明这个幂可能放在a上,也可能在b上,那么这就
需要注意:若题目给出的gcd,lcm都等于0或者互质那么答案一定是0;
<pre name="code" class="html"><span style="font-family:Comic Sans MS;font-size:18px;">#include<cmath> #include<cstdio> #include<iostream> using namespace std; int prime[5000000],num[5000000],gcd[1000010],lcm[1000010]; bool vis[1000010]; long long pow(int x,int p){ long long ans=1; while(p){ if(p&1)ans*=x; x*=x; p=p>>1; } return ans; } int main(){ int T; cin>>T; int max1=0; for(int i=1;i<=T;i++){ scanf("%d%d",&gcd[i],&lcm[i]);; max1=max(max1,lcm[i]); } for(int i=2;i<=sqrt(max1)+1;i++) for(int j=i;i*j<=max1;j++) vis[i*j]=true; int cnt=0; for(int i=2;i<=max1;i++) if(!vis[i])prime[++cnt]=i;//把质数都拿出来 for(int 4000 i=1;i<=T;i++){ int m=gcd[i],n=lcm[i]; if(n==0||m==0){ cout<<"0"<<endl; continue; } int flag=0;//记录一个flag,如果gcd和lcm有至少一个公共的因子,那么flag变为1,否则说明他们互质 int ans=0,loc=1; while(m!=1||n!=1){//当两个全都为一时停止运算。 int count1=0,count2=0; while((m%prime[loc])==0){ m/=prime[loc]; count1++; } while((n%prime[loc])==0){ n/=prime[loc]; count2++; } if(count1!=count2){ ans++; } if(count1>0&&count2>0) flag=1; //如果他们有共同的因子,说明不互质 loc++; } if(flag==0&&gcd[i]!=1){ cout<<"0"<<endl; break; } cout<<pow(2,ans)<<endl;//快速幂 } }</span>
相关文章推荐
- codevs 4712 gcd与lcm问题
- cjoj1491 【NOIP2001】GCD和LCM问题
- 【GCD|LCM】最大公约数和最小公倍数问题 WIKIOI1012
- GCD&&LCM的一些经典问题
- C++/C经典算法百题--(39-42)年龄几何,三色球问题,两个正整数的最大公约数和(GCD)和最小公倍数(LCM)
- GCD&&LCM的一些经典问题
- 数学问题——进制&GCD&LCM
- POJ 2429 GCD & LCM Inverse (整数分解,由gcd+lcm求a,b)
- 2429 GCD & LCM Inverse 大整数分解质因数
- hdu 1019(gcd & lcm)
- GCD & LCM 一个神奇的式子
- 数论(一)——素数,GCD,LCM
- poj 2429 GCD & LCM Inverse
- 求两个或N个数的最大公约数(gcd)和最小公倍数(lcm)的较优算法
- HDOJ2503 ( a/b + c/d ) 【最大公约数GCD,最小公倍数LCM】
- poj 2429 GCD & LCM Inverse
- gcd 与 lcm
- PKU 2429 GCD & LCM Inverse
- ZOJ 1577 GCD & LCM
- gcd&lcm模板(poj3101验证)