codeforces 615 D. Multipliers (数论 + 小费马定理 + 素数)
题目链接:
题目描述:
给出n个素数,这n个素数的乘积等于s,问p的所有因子相乘等于多少?
解题思路:
需要求出每一个素数的贡献值,设定在这n个素数中,有m个不同的素数,可表示为s = p1^a1*p1^a2*p3^a3*p4^a4.....pn^an,根据唯一分解定理可知,s的因子有(a1+1)*(a2+1)+......+(an+1) 个,对于pi的权值可以理解为:pi这个因子不出现,s的因子个数为x = (a1+1)*(a2+1)*...*(ai-1+1)*(ai+1+1)*...*(an+1),而因子pi出现的策略有y = (ai+1)*ai/2种,所以pi的贡献值为:pix * y,对于 x 值可以利用前缀来维护,还有就是因为x * y可能会很大,对指数进行取余,要用小费马定理:(a^b)%mod = a^(b%(mod-1))%mod。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <map> 8 #include <queue> 9 using namespace std; 10 #define LL __int64 11 12 const LL mod = 1e9+7; 13 const int maxn = 200200; 14 15 map <LL, LL> mp; 16 LL ans, l[maxn], r[maxn], res[maxn]; 17 18 LL Pow (LL x, LL n) 19 { 20 LL sum = 1; 21 while (n) 22 { 23 if (n % 2) 24 sum =(sum * x) % mod; 25 x =(x * x) % mod; 26 27 n /= 2; 28 } 29 return sum; 30 } 31 32 /** 33 题意:给出n个素数,求素数的乘积的约数的乘积在MOD上一个数 34 逆元 35 a^n%m= a^(n mod(m-1))%m; 36 */ 37 int main () 38 { 39 LL m; 40 scanf ("%I64d", &m); 41 { 42 LL n = 0, x; 43 ans = 1; 44 45 for (int i=0; i<m; i++) 46 { 47 scanf ("%I64d", &x); 48 49 if (mp[x] == 0) 50 res[++ n] = x; 51 52 mp[x] ++; 53 } 54 55 sort (res, res+n); 56 l[0] = r[n+1] = 1; 57 for (int i=1; i<=n; i++) 58 { 59 l[i] = (l[i-1] * (mp[res[i]] + 1)) % (mod - 1); 60 r[n-i+1] = (r[n-i+2] * (mp[res[n-i+1]] + 1)) % (mod -1); 61 } 62 63 for (int i=1; i<=n; i++) 64 { 65 LL tmp = (mp[res[i]] + 1) * mp[res[i]] / 2 % (mod -1) * l[i-1] % (mod -1) * r[i+1] % (mod - 1); 66 ans = (ans * Pow(res[i], tmp))%mod; 67 } 68 69 printf ("%I64d\n", ans); 70 } 71 return 0; 72 } 73 /** 74 6 75 101 103 107 109 101 103 76 77 */
本文为博主原创文章,未经博主允许不得转载。