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  }

 

 

posted @ 2012-10-09 19:50  Gu Feiyang  阅读(478)  评论(0)    收藏  举报