超级幂的弱化版本这里
然后就是把底数k求出来,假设p是n的一个质因数,因为n无平方因子,所以
gcd(n,pn)=1
,所以可以得到
f(n,m)=∑i=1mϕ(i×n)=ϕ(p)∑i=1&&i%p≠0mϕ(i×np)+∑i=1mpϕ(i×p×n)=ϕ(p)∑i=1&&i%p≠0mϕ(i×np)+p∑i=1mpϕ(i×n)=ϕ(p)∑i=1&&i%p≠0mϕ(i×np)+(ϕ(p)+1)∑i=1mpϕ(i×n)=ϕ(p)∑i=1mϕ(i×np)+∑i=1mpϕ(i×n)=ϕ(p)f(np,m)+f(n,mp)
接下来就暴力递归。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
#define maxn 10050000
#define mod 1000000007
bool vis[maxn];
int phi[maxn], prime[maxn], cnt, sum[maxn];
int fac[maxn];
void init () {
cnt = 0;
memset (vis, 0, sizeof vis);
phi[1] = 1;
for (int i = 2; i < maxn; i++) {
if (!vis[i]) {
prime[cnt++] = i;
fac[i] = i;
phi[i] = i-1;
}
for (int j = 0; j < cnt; j++) {
if (1LL*i*prime[j] >= maxn) break;
vis[i*prime[j]] = 1;
fac[i*prime[j]] = prime[j];
if (i%prime[j] == 0) {
phi[i*prime[j]] = phi[i] * prime[j];
break;
}
else {
phi[i*prime[j]] = phi[i] * (prime[j]-1);
}
}
}
sum[0] = 0;
for (int i = 1; i < maxn; i++) {
sum[i] = sum[i-1]+phi[i];
sum[i] %= mod;
}
}
long long n, m, p, k;
long long qpow (long long a, long long b, int p) {
if (b == 0)
return 1%p;
long long ans = qpow (a, b>>1, p);
ans = ans*ans%p;
if (b&1)
ans = ans*a%p;
return ans;
}
long long cal (int n, int m) {
if (!n || !m)
return 0;
if (n == 1)
return sum[m];
if (m == 1)
return phi[n];
return (1LL*phi[fac[n]] * cal (n/fac[n], m) % mod + cal (n, m/fac[n])) % mod;
}
long long solve (int p) {
if (p == 1)
return 0;
long long ans = solve (phi[p]);
ans += phi[p];
return qpow (k, ans, p);
}
int main () {
init ();
while (scanf ("%lld%lld%lld", &n, &m, &p) == 3) {
k = cal (n, m);
printf ("%lld\n", solve (p));
}
return 0;
}