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

 

你可能感兴趣的:(HDU)