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
");
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
",ans);
48     }
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/allh123/p/3279747.html