hdu 4497 GCD and LCM 质因素分解+排列组合or容斥原理

//昨天把一个i写成1了 然后挂了一下午

首先进行质因数分解g=a1^b1+a2^b2...... l=a1^b1'+a2^b2'.......,然后判断两种不可行情况:1,g的分解式中有l的分解式中没有的质因子 2,存在bi>bi',然后剩下的都是可行解,对于每一个质因子三个数中有两个分别bi,bi',第三个的取值可为[bi,bi'],所以对于每一个质因子共有6(bi-bi')种取法(A(2,3)*(b-a+1)+C(2,3)*2分别为取得值在和不在边界上的情况,特殊:如果bi=bi'就只有一种取法),然后分步乘法乘起来就好。

其实也可以用容斥原理:(bi'-bi+1)^3-2*(bi'-bi)^3+(bi'-bi-1)^3,那个数随便选,减去在上边界减去在下边界,然后减多了,在加上既在上边界又在下边界的。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #include<stack>
11 #include<string>
12 
13 using namespace std;
14 
15 long long T;
16 long long g,l;
17 long long f[500000][3];
18 
19 void solve(){
20     memset(f,0,sizeof(f));
21     scanf("%I64d%I64d",&g,&l);
22     long long now_num=2;
23     long long t=0;
24     while (l!=1){
25             while (l%now_num==0){
26                     if (f[t][0]!=now_num){
27                         f[++t][0]=now_num;
28                     }
29                     f[t][1]++;
30                     l=l/now_num;
31             }
32             now_num++;
33     }
34     for (long long i=1;i<=t;i++){
35             while (g%f[i][0]==0){
36                     f[i][2]++;
37                     g=g/f[i][0];
38             }
39     }
40     if (g!=1){
41             printf("0\n");
42             return;
43     }
44     long long ans=1;
45     for (long long i=1;i<=t;i++){
46             if (f[i][1]<f[i][2]){
47                     printf("0\n");
48                     return;
49             }
50             if (f[i][1]!=f[i][2]){
51                     long long tmp=(f[i][1]-f[i][2]+1)*(f[i][1]-f[i][2]+1)*(f[i][1]-f[i][2]+1);
52                     tmp=tmp-(2*(f[i][1]-f[i][2])*(f[i][1]-f[i][2])*(f[i][1]-f[i][2]));
53                     tmp=tmp+(f[i][1]-f[i][2]-1)*(f[i][1]-f[i][2]-1)*(f[i][1]-f[i][2]-1);
54                     ans=ans*tmp;
55             }
56     }
57     printf("%I64d\n",ans);
58 }
59 
60 int main(){
61     scanf("%I64d",&T);
62     for (long long cas=1;cas<=T;cas++){
63             solve();
64     }
65     return 0;
66 }
67 /*
68 1
69 15 5160
70 
71 3
72 6 6
73 6 72
74 7 33
75 
76 3
77 15 5160
78 9424 375981972
79 998 810
80 */
View Code

 

posted @ 2015-07-14 14:01  鼠宝宝  阅读(235)  评论(0编辑  收藏  举报