感觉智商被掏空…
定义 k=∑mi=1φ(i·n) mod 1000000007
n 是无质因子平方项的数.
求 ans=kkkk...k( mod p) ,其中k有无穷多个
数据范围: 1≤n,m,p≤107
题意很清晰啦。数据范围这么大,肯定要先化简。
n 是无质因子平方项的数.这个条件很关键,说明任取n中的因子g,满足 gcd(g,ng)=1(∗)
取i,满足 gcd(i,n)=g ,则 gcd(ig,ng)=1 ,综合 (∗)可得gcd(g2×ig,ng)=1
则由 φ(i·n)=φ(i·g·ng)=φ(i·g)φ(ng)
又 g∣i ,则 φ(i·g)=g·φ(i)
所以看了题解,不按套路啊…
任取n中的质数p,若 p∣i ,则 p2∣i·n ,则由引理1: φ(i·n)=p·φ(i·np)
若 p∤i ,则 p2∤i·n ,则由引理2: φ(i·n)=(p−1)φ(i·np)
map, S>
里,不用反复查询。
然后看看 ans=kkkk...k( mod p)
两种错误的想法,样例都不能过,不想清楚还是很抓狂…
认为 ans=kans( mod p) 或者 ans=ansk( mod p) 的,就不要玩了。
一般情况下, ax≢ax%p(modp)
令 A(k,p)=kkkk...k( mod p)
由引理3, kb≡kφ(p)+b%φ(p)(modp) , b=kkkk...k ,可得
#include
using namespace std;
#define N 10000010
#define LL long long
int MOD = 1000000007;
int num[N], prim[N], phi[N], sum[N];
int pn = 0;
void init(){
memset(num, -1, sizeof(num));
phi[0] = phi[1] = 1;
for(int i = 2;i < N;i++){
if(num[i]){
prim[pn++] = i;
phi[i] = i-1;
}
for(int j = 0;j < pn && 1LL*i*prim[j] < N;j++){
if(i % prim[j] == 0){
phi[i*prim[j]] = phi[i] * prim[j];
num[i*prim[j]] = 0;
break;
}
phi[i*prim[j]] = phi[i] * (prim[j] - 1);
num[i*prim[j]] = 0;
}
}
sum[0] = 0;
for(int i = 1;i < N;i++)
sum[i] = 1LL*(sum[i-1] + phi[i]) % MOD;
}
int s(int n, int m){
if(n == 1)
return sum[m];
if(m == 0)
return 0;
for(int i = 0;i < pn && prim[i] <= n;i++){
if(n % prim[i] == 0){
int p = prim[i];
return (1LL*(p-1)*s(n/p, m)%MOD + s(n, m/p)%MOD)%MOD;
}
}
}
LL poo(LL a, int k, int m){
LL res = 1;
while(k){
if(k & 1LL) res = res*a%m;
k >>= 1;
a = a*a%m;
}
return res;
}
int A(int k, int p){
if(p == 1) return 0;
if(k == 1) return 1;
return poo(1LL*k%p, phi[p]+A(k, phi[p]), p);
}
int main(){
init();
int n, m, p;
while(~scanf("%d%d%d", &n, &m, &p)){
int k = s(n, m);
int ans = A(k, p);
printf("%d\n", ans);
}
return 0;
}