Codeforces 615D Multipliers (数论)

题目链接 Multipliers

题意很明确。

很显然答案可以表示成X ^ EXP % MOD

首先我们令N为输入的n个数的乘积。并且设N = (P1 ^ C1) * (P2 ^ C2) * ... * (Pk * Ck),Pi(1 <= i <= k)为质数。

1、N为完全平方数。

   这个时候X = N的算术平方根,EXP = (C1 +1) * (C2 + 1) * ... * (Ck + 1), MOD = 1e9 + 7;

2、N不是完全平方数。

   这个时候X = N, EXP = (C1 +1) * (C2 + 1) * ... * (Ck + 1) / 2, MOD = 1e9 + 7;

考虑到EXP可能非常大,这里我用了指数循环节公式:

 a^b%c = a^( b%phic+phic )%c phix为欧拉函数。

而在题中c等于1e9 + 7为质数,那么phic = 1e9 + 6。

剩下的事情就很简单了。

 

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define rep(i, a, b)  for(int i(a); i <= (b); ++i)
 6 #define LL            long long
 7 
 8 const int N     =    200010;
 9 const LL mod    =    1000000007;
10 
11 int prime[N];
12 int c[N], d[N];
13 bool fl;
14 int cnt = 0;
15 int n, x;
16 int squ;
17 
18 map <int, int> mp;
19 
20 
21 inline LL Pow(LL a, LL b, LL Mod){ 
22     LL ret(1); 
23     for (; b; b >>= 1, (a *= a) %= Mod) 
24         if (b & 1) (ret *= a) %= Mod; 
25     return ret;
26 }    
27 
28 
29 int main(){
30 
31     rep(i, 2, 200000){
32         fl = true;
33         rep(j, 2, (int)sqrt(i + 0.5)) if (i % j == 0){
34             fl = false;
35             break;
36         }
37         if (fl){
38             prime[++cnt] = i;
39             mp[prime[cnt]] = cnt;
40         }
41     }
42 
43     memset(c, 0, sizeof c);
44 
45     scanf("%d", &n);
46     rep(i, 1, n){
47         scanf("%d", &x);
48         ++c[mp[x]];
49     }
50 
51     squ = 1;
52     rep(i, 1, cnt)
53         if (c[i]){
54             if (c[i] & 1){
55                 squ = 0;
56                 break;
57             }
58         }
59         
60 
61     LL exp = 1;
62     if (squ){
63         LL ret = 1;
64         rep(i, 1, cnt) d[i] = c[i] / 2;
65         rep(i, 1, cnt) ++c[i];
66         rep(i, 1, cnt) (exp *= c[i]) %= (mod - 1);
67 
68         rep(i, 1, cnt) if (d[i]) (ret *= Pow(prime[i], d[i], mod)) %= mod;
69 
70         printf("%lld\n", Pow(ret, exp + mod - 1, mod));    
71     }
72 
73     else
74     {
75         rep(i, 1, cnt) d[i] = c[i] + 1;
76         rep(i, 1, cnt) if (d[i] % 2 == 0){
77             d[i] >>= 1;
78             break;
79         }
80 
81         LL exp = 1;
82         rep(i, 1, cnt) (exp *= d[i]) %= (mod - 1);
83         LL ret = 1;
84         rep(i, 1, cnt) if (c[i]) (ret *= Pow(prime[i], c[i], mod)) %= mod;
85         
86         printf("%lld\n", Pow(ret, exp + mod - 1, mod));
87     }
88     
89 
90     return 0;
91 
92 }

 

posted @ 2017-02-14 13:17  cxhscst2  阅读(280)  评论(0编辑  收藏  举报