HDU 4497 数论+组合数学
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4497
解题思路:将满足条件的一组x,z,y都除以G,得到x‘,y',z',满足条件gcd(x',y',x') = 1,同时lcm(x',y',x') = G/L.
特判,当G%L != 0 时,无解。
然后素数分解G/L,假设G/L = p1^t1 * p2^t2 *````* pn^tn。
满足上面条件的x,y,z一定为这样的形式。
x' = p1^i1 * p2^i2 *```* pn^in.
y' = p1^j1 * p2^j2 * ```*pn^jn.
z' = p1^k1 * p2^k2 * ```*pn^kn.
为了满足上面的条件,对于p1,一定有max(i1,j1,k1) = t1.min(i1,j1,k1) =0;则当选定第一个数为0,第二个数为t1时,第三个数可以为0-t1,又由于有顺序的,只有
(0,t1,t1) 和(0,t1,0)这两种情形根据顺序只能产生四种结果,其他的由于三个数都不一样,一定能产生6种,所以最后产生了6*(t1-1)+3*2 = 6*t1种,根据乘法原理以及关于素数分解的唯一性,反过来,素数组合必然也是唯一的数,一共有6*t1 * 6*t2 *`````*6*tn种选法。
另一种思考:容斥原理,对于p1,一共有(t1+1)^3种,但是没有最高位t1的选法是不合法的,减去,一共有t1^3种选法不合法,没有最低位0的选法是不合法的,也是t1^3,发现多减了,所以加上多减的既没有最高位也没有最低位的(t1-1)^3,通过化简得6*t1`````
贴代码:
1 #include<cstdio> 2 #include<cmath> 3 #define N 100005 4 int a[N],b[N]; 5 void factor(int n,int &tot) 6 { 7 int temp,i; 8 temp =(int)(sqrt(n) +1); 9 tot =-1; 10 for(int i=2; i <= temp; ++i) 11 { 12 if(n%i == 0) 13 { 14 a[++tot] = i; 15 b[tot] = 0; 16 while(n%i == 0) 17 { 18 ++b[tot]; 19 n /= i; 20 } 21 } 22 } 23 if(n != 1) 24 { 25 a[++tot] = n; 26 b[tot] = 1; 27 } 28 } 29 int main() 30 { 31 // freopen("in.txt","r",stdin); 32 int t,G,L; 33 scanf("%d",&t); 34 while(t--) 35 { 36 scanf("%d%d",&G,&L); 37 if(L%G != 0) 38 { 39 printf("0\n"); 40 continue; 41 } 42 L = L/G; 43 int tot; 44 factor(L,tot); 45 long long int ans =1; 46 for(int i=0; i<=tot; ++i) ans *= (6*b[i]); 47 printf("%I64d\n",ans); 48 } 49 return 0; 50 }