JZOJ 5809. 【NOIP2008模拟】数羊

Description

牧羊人A和牧羊人B总是很无聊,所以他们要玩一个游戏。A有a只羊,B有b只羊。他们想要知道a^b的因子和是多少。这就很为难两个牧羊人了,由于答案太大,你能不能告诉我答案取模9901的数。
 

Input

仅一行,为两个正整数a和b

Output

a^b的因子和对9901的余数。
 

Sample Input

2 3

Sample Output

15

Data Constraint

对于100%的数据,0≤a,b≤50000000
 
做法:先将a质因数分解,然后将每个指数乘上b,然后根据因子求和公式,计算等比数列就好啦,由于涉及到除法,我们需要使用逆元,数据保证不会是9901的倍数。。。
 
代码如下:
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cmath>
 5 #define LL long long
 6 #define mo 9901
 7 #define N 50000007
 8 using namespace std;
 9 LL a, b, ans, Have[N / 5];
10 int Pri[N / 5], S[N / 5];
11 bool v[N];
12 
13 void Pre_work()
14 {
15     Pri[1] = 2, Pri[0] = 1;
16     for (int i = 3; i <= N - 2; i += 2)
17     {
18         if (!v[i])    Pri[++Pri[0]] = i;
19         for (int j = 1; j <= Pri[0] && i * Pri[j] < N - 2; v[i * Pri[j]] = 1, j++);
20     }
21 }
22 
23 LL Fastpow(LL x, LL y)
24 {
25     LL ret = 1;
26     x %= mo;
27     while (y)
28     {
29         if (y & 1) ret = (ret * x) % mo;
30         y >>= 1;
31         x = (x * x) % mo;
32     }
33     return ret;
34 }
35 
36 int main()
37 {
38 //    freopen("sheep.in", "r", stdin);
39 //    freopen("sheep.out", "w", stdout);
40     Pre_work();
41     scanf("%lld%lld", &a, &b);
42     LL p = a;
43     for (int i = 1; p > 1; )
44     {
45         while (p % Pri[i] != 0)    i++;
46         LL sum = 1;
47         while (p % Pri[i] == 0) Have[i]++, p /= Pri[i];
48         Have[i] *= b;
49         S[++S[0]] = i;
50     }
51     ans = 1;
52     for (int i = 1; i <= S[0]; i++)
53     {
54         LL v = Fastpow(1 - Pri[S[i]], mo - 2); 
55         LL u = Fastpow(Pri[S[i]], Have[S[i]]);
56         u = (1 - u * Pri[S[i]]) % mo;
57         ans = (ans * u * v) % mo;
58     }
59     printf("%lld", ans);
60 }
View Code
原文地址:https://www.cnblogs.com/traveller-ly/p/9472293.html