Product You are given positive integers $n$ ( $n \le 10^9$), $m$ ( $m \le 2 \times 10^9$), $p$ ($p \le 2 \times 10^9$) and you need to calculate the following product modulo $p$.
Each test file contains a single test case. In each test file:
There are three positive integers $n$, $m$, $p$ which are separated by spaces. It is guaranteed that $p$ is a prime number.
Output An integer representing your answer.
样例输入1
样例输出1
样例输入2
样例输出2
样例输入3 1 1000000000 999999997 98765431
样例输出3
题意 请看题目描述
解决方案 对原式进行化简:
先考虑指数部分:
首先考虑后面一部分,可以用杜教筛求出其前缀和,回顾一下杜教筛的推导过程:
其中 $g(n)$ 是需要我们自己构造的函数。
用杜教筛求 $\phi(n)$ 的前缀和时,我们令 $g(n) = I(n)$ ,则 $h(n) = id(n)$ ,所以有:
后面一部分可以用杜教筛分块了,那前面一部分的前缀和呢?
推导如下:
之后,这一部分也可以分块解决了,至此,此题公式推导完毕。
但是还没有结束,因为我们只是处理了指数部分,实际要求的是一个乘方。很明显感觉到,这个指数是会爆 long long 的,那么就要考虑欧拉降幂,题目也明说了答案对 $p$ 取模,且 $p$ 是一个质数,所以必有 $\gcd(m,p)=1$ ,那么结合欧拉降幂的公式,可得:
所以在公式中分块求和的时候记得对 $p - 1$ 取模,最后再跑一个快速幂就好了。
代码 注意要把 $k\cdot d(k)$ 也筛出来一部分,不然会 T。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 #include <bits/stdc++.h> using namespace std ;typedef long long ll;const int maxn = 8e6 + 10 ;ll mod; bool vis[maxn];int prime[maxn];ll phi[maxn]; ll d[maxn]; int low[maxn];int tot;unordered_map <int , ll> mp;void eular () { vis[0 ] = vis[1 ] = true ; phi[1 ] = d[1 ] = 1 ; for (int i = 2 ; i < maxn; i++) { if (!vis[i]) { prime[tot++] = i; phi[i] = i - 1 ; d[i] = 2 ; low[i] = 1 ; } for (int j = 0 ; j < tot && i * prime[j] < maxn; j++) { vis[i * prime[j]] = true ; if (i % prime[j]) { phi[i * prime[j]] = phi[i] * (prime[j] - 1 ); d[i * prime[j]] = d[i] * 2 ; low[i * prime[j]] = 1 ; } else { phi[i * prime[j]] = phi[i] * prime[j]; d[i * prime[j]] = d[i] / (low[i] + 1 ) * (low[i] + 2 ); low[i * prime[j]] = low[i] + 1 ; break ; } } } for (int i = 1 ; i < maxn; i++) { phi[i] = (phi[i - 1 ] + phi[i]) % mod; d[i] = (i * d[i] + d[i - 1 ]) % mod; } } ll get_sum (int x) { if (x < maxn) { return d[x]; } ll ans = 0 ; for (int l = 1 , r; l <= x; l = r + 1 ) { r = x / (x / l); ll t1 = (1l l * (l + r) * (r - l + 1 ) / 2 ) % mod; ll t2 = (1l l * (x / l) * (x / l + 1 ) / 2 ) % mod; ans = (ans + t1 * t2) % mod; } return ans; } ll djs_phi (int x) { if (x < maxn) { return phi[x]; } if (mp.count(x)) { return mp[x]; } ll ans = 0 ; for (int l = 2 , r; l <= x; l = r + 1 ) { r = x / (x / l); ans += (r - l + 1 ) * djs_phi(x / l) % mod; ans %= mod; } ll tmp = (1l l * x * (x + 1 ) / 2 ) % mod; ans = (tmp - ans + mod) % mod; return mp[x] = ans; } ll quick_mod (ll a, ll b, ll c) { a %= c; ll ans = 1 ; while (b) { if (b & 1 ) { ans = ans * a % c; } a = a * a % c; b >>= 1 ; } return ans; } int main () { int n, m, p; scanf ("%d%d%d" , &n, &m, &p); mod = p - 1 ; eular(); ll sum = 0 ; for (int l = 1 , r; l <= n; l = r + 1 ) { r = n / (n / l); ll t1 = get_sum(r) - get_sum(l - 1 ); t1 = (t1 + mod) % mod; ll t2 = 2 * djs_phi(n / l) - 1 ; sum = (sum + t1 * t2) % mod; } printf ("%lld\n" , quick_mod(m, sum, p)); return 0 ; }