【CODECHEF】【phollard rho + miller_rabin】The First Cube

All submissions for this problem are available.

Read problems statements in Mandarin Chinese and Russian.

This problem's statement is really a short one.

You are given an integer S. Consider an infinite sequence S, 2S, 3S, ... . Find the first number in this sequence that can be represented as Q3, where Q is some positive integer number. As the sought number could be very large, please print modulo (109 + 7).

The number S will be given to you as a product of N positive integer numbers A1, A2, ..., AN, namely S = A1 * A2 * ... * AN

Input

The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.

The first line of each test case contains an integer N.

Then there is a line, containing N space separated integers, denoting the numbers A1, A2, ..., AN.

Output

For each test case, output a single line containing the first term of the sequence which is the perfect cube, modulo 109+7.

Constraints

  • 1T10
  • (Subtask 1): N = 1, 1S109 - 15 points.
  • (Subtask 2): N = 1, 1S1018 - 31 point.
  • (Subtask 3): 1N100, 1Ai1018 - 54 points.

Example

Input:
2
2
2 2
2
2 3
Output:
8
216

Explanation

Example case 1. First few numbers in the infinite sequence 4, 8, 12, 16, 20, , etc. In this sequence, 8 is the first number which is also a cube (as 23 = 8).

Example case 2. First few numbers in the infinite sequence 6, 12, 18, 24, , etc. In this sequence, 216 is the first number which is also a cube (as 63 = 216).

【分析】

挺模板的东西,就当复习一下了。

  1 /*
  2 宋代李冠
  3 《蝶恋花·春暮》
  4 遥夜亭皋闲信步。
  5 才过清明,渐觉伤春暮。
  6 数点雨声风约住。朦胧淡月云来去。
  7 桃杏依稀香暗渡。
  8 谁在秋千,笑里轻轻语。
  9 一寸相思千万绪。人间没个安排处。 
 10 */
 11 #include <cstdio>
 12 #include <cstring>
 13 #include <algorithm>
 14 #include <cmath>
 15 #include <queue>
 16 #include <vector>
 17 #include <iostream>
 18 #include <string>
 19 #include <ctime>
 20 #include <map>
 21 #define LOCAL
 22 const int MAXN = 105 + 10;
 23 const long long MOD = 1000000007;
 24 const double Pi = acos(-1.0);
 25 long long G = 15;//原根 
 26 const int MAXM = 60 * 2 + 10; 
 27 using namespace std;
 28 typedef long long ll;
 29 ll read(){
 30    ll flag = 1, x = 0;
 31    char ch;
 32    ch = getchar();
 33    while (ch < '1' || ch > '9') {if (ch == '-') flag = -1; ch = getchar();}
 34    while (ch >= '0' && ch <= '9') {x = x * 10 + (ch - '0'); ch = getchar();}
 35    return x * flag;
 36 }
 37 map<ll, int>Num;//记录个数
 38 ll data[MAXN]; 
 39 ll n;
 40 
 41 ll mul(ll a, ll b, ll c){//又要用快速乘QAQ
 42    if (b == 0) return 0ll;
 43    if (b == 1) return a % c;
 44    ll tmp = mul(a, b / 2, c);
 45    if (b % 2 == 0) return (tmp + tmp) % c;
 46    else return (((tmp + tmp) % c) + (a % c)) % c;
 47 }
 48 ll pow(ll a, ll b, ll c){
 49    if (b == 0) return 1ll;
 50    if (b == 1) return a % c;
 51    ll tmp = pow(a, b / 2, c);
 52    if (b % 2 == 0) return mul(tmp, tmp, c);
 53    else return mul(mul(tmp, tmp, c), a, c);
 54 }
 55 bool Sec_check(ll a, ll b, ll c){
 56      ll tmp = pow(a, b, c);
 57      if (tmp != 1 && tmp != (c - 1)) return 0;
 58      if (tmp == (c - 1) || (b % 2 != 0)) return 1; 
 59      return Sec_check(a, b / 2, c);
 60 }
 61 //判断n是否是素数 
 62 bool miller_rabin(ll n){
 63      int cnt = 20;
 64      while (cnt--){
 65            ll a = (ll)rand() % (n - 1) + 1;
 66            if (!Sec_check(a, n - 1, n)) return 0;
 67      } 
 68      return 1;
 69 }
 70 ll gcd(ll a, ll b){return b == 0ll ? a : gcd(b, a % b);}
 71 ll pollard_rho(ll a, ll c){
 72    ll i = 1, k = 2;
 73    ll x, y, d;
 74    x = (ll)((double)(rand() / RAND_MAX) * (a - 2) + 0.5) + 1ll; 
 75    y = x;
 76    while (1){
 77          i++;
 78          x = (mul(x, x, a) % a + c) % a;
 79          d = gcd(y - x + a, a);
 80          if (d > 1 && d < a) return d;
 81          if (y == x) return a;//失败
 82          if (i == k){
 83             k <<= 1;
 84             y = x;
 85          }
 86    }
 87 }
 88 void find(ll a, ll c){
 89      if (a == 1) return;
 90      if (miller_rabin(a)){
 91         Num[a]++;
 92         return;
 93      }
 94      ll p = a;
 95      while (p >= a) pollard_rho(a, c--);
 96      pollard_rho(p, c);
 97      pollard_rho(a / p, c);
 98 }
 99 void init(){
100      Num.clear();
101      scanf("%d", &n);
102      for (int i = 1; i <= n; i++) {
103          data[i] = read();
104          find(data[i], 15000);
105      }
106 } 
107 void work(){
108      ll Ans = 1;
109      for (int i = 1; i <= n; i++) Ans = (Ans * data[i]) % MOD;
110      for (map<ll, int>::iterator it = Num.begin(); it != Num.end(); it++){
111          it->second %= 3;
112          if (it->second){
113             for (int i = it->second; i < 3; i++) Ans = (Ans * ((it->first) % MOD)) % MOD;
114          }
115      }
116      printf("%lld\n", Ans);
117 }
118 
119 int main(){
120     int T;
121     
122     scanf("%d", &T);
123     while (T--){
124           init();
125           work();
126     }
127     return 0;
128 }
View Code

 

posted @ 2015-03-31 21:26  TCtower  阅读(356)  评论(0编辑  收藏  举报