Light 1236 最小公倍数是n的对数
题意:给出了一个n,现在要求出最小公倍数是n的对数。
思路: 对n进行因子分解, 将n写成p1^(k1) *p2^(k2)........pm*(km).的形式。
那么答案就是( (2k1+1)*(2k2+1)*.......(2km+1)+1 )/2.
其原理是对于每个因子单独看, 那么对于每个因子有2*k+1中情况。
将所有因子的情况相乘, 这样最后得出的答案中,每对计算了两次(除了<n,n>),最后的答案是(ans+1)/2;
AC代码:
View Code
1 #pragma comment (linker,"/STACK:10240000000,10240000000") 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 #include <ctime> 7 #include <cstdlib> 8 #include <iostream> 9 using namespace std; 10 typedef long long LL; 11 const int TIME = 12; 12 13 LL factor[100]; 14 int fac_top = -1; 15 LL n; 16 17 LL gcd(LL a, LL b) 18 { 19 while(a) 20 { 21 swap(a,b); 22 a %= b; 23 } 24 if(b > 0) return b; 25 return -b; 26 } 27 28 LL muti_mod(LL a, LL b, LL n) 29 { 30 LL exp = a%n, res = 0; 31 while(b) 32 { 33 if(b&1) 34 { 35 res += exp; 36 if(res > n) res -= n; 37 } 38 exp <<= 1; 39 if(exp > n) exp -= n; 40 b >>= 1; 41 } 42 return res; 43 } 44 45 LL mod_exp(LL a, LL p, LL m) 46 { 47 LL exp = a%m, res = 1; 48 while(p>1) 49 { 50 if(p&1) 51 res = muti_mod(res, exp, m); 52 exp = muti_mod(exp, exp, m); 53 p >>= 1; 54 } 55 return muti_mod(res, exp, m); 56 } 57 58 bool miller_rabin(LL n, int times) 59 { 60 if(n == 2) return 1; 61 if(n<2 || !(n&1)) return 0; 62 LL a, u=n-1, x, y; 63 int t=0; 64 while(u%2 == 0) 65 { 66 t++; 67 u /= 2; 68 } 69 srand(time(0)); 70 for(int i=0; i<times; i++) 71 { 72 a = rand()%(n-1)+1; 73 x = mod_exp(a, u, n); 74 for(int j=0; j<t; j++) 75 { 76 y = muti_mod(x, x, n); 77 if(y == 1 && x!=1 && x!=n-1) 78 return false; 79 x = y; 80 } 81 if(y != 1) return false; 82 } 83 return true; 84 } 85 86 LL pollard_rho(LL n, int c) 87 { 88 LL x, y, d, i=1, k=2; 89 srand(time(0)); 90 x = rand()%(n-1) + 1; 91 y = x; 92 while(1) 93 { 94 i++; 95 x = (muti_mod(x,x,n) + c) % n; 96 d = gcd(y-x, n); 97 if(1<d && d<n) return d; 98 if(y == x) return n; 99 if(i == k) 100 { 101 y = x; 102 k <<= 1; 103 } 104 } 105 } 106 107 void findFactor(LL n, int k) 108 { 109 if(n == 1) return ; 110 if(miller_rabin(n, TIME)) 111 { 112 factor[++fac_top] = n; 113 return ; 114 } 115 LL p = n; 116 while(p >= n) 117 p = pollard_rho(p,k--); 118 findFactor(p, k); 119 findFactor(n/p, k); 120 } 121 122 void solve() 123 { 124 sort(factor, factor+fac_top+1); 125 LL ans = 1, tp=1, pre = factor[0]; 126 for(int i=1; i<=fac_top; i++) 127 { 128 if(factor[i] == pre) 129 tp++; 130 else 131 { 132 ans *= (tp*2 + 1); 133 tp = 1; 134 pre = factor[i]; 135 } 136 } 137 ans *= (2*tp+1); 138 printf("%lld\n", (ans+1)/2); 139 } 140 141 int main() 142 { 143 int t; 144 scanf("%d", &t); 145 for(int i=1; i<=t; i++) 146 { 147 scanf("%lld", &n); 148 fac_top = -1; 149 printf("Case %d: ",i); 150 if(n == 1) 151 { 152 printf("1\n"); 153 continue; 154 } 155 if(miller_rabin(n,TIME)) 156 printf("%d\n",2); 157 else 158 { 159 findFactor(n, 1000); 160 solve(); 161 } 162 } 163 return 0; 164 }


浙公网安备 33010602011771号