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 */