猪王国的文明源远流长,博大精深。
iPig在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为N。当然,一种语言如果字数很多,字典也相应会很大。当时的猪王国国王考虑到如果修一本字典,规模有可能远远超过康熙字典,花费的猪力、物力将难以估量。故考虑再三没有进行这一项劳猪伤财之举。当然,猪王国的文字后来随着历史变迁逐渐进行了简化,去掉了一些不常用的字。
iPig打算研究古时某个朝代的猪文文字。根据相关文献记载,那个朝代流传的猪文文字恰好为远古时期的k分之一,其中k是N的一个正约数(可以是1和N)。不过具体是哪k分之一,以及k是多少,由于历史过于久远,已经无从考证了。
iPig觉得只要符合文献,每一种能整除N的k都是有可能的。他打算考虑到所有可能的k。显然当k等于某个定值时,该朝的猪文文字个数为N / k。然而从N个文字中保留下N / k个的情况也是相当多的。iPig预计,如果所有可能的k的所有情况数加起来为P的话,那么他研究古代文字的代价将会是G的P次方。
现在他想知道猪王国研究古代文字的代价是多少。由于iPig觉得这个数字可能是天文数字,所以你只需要告诉他答案除以999911659的余数就可以了。
输出有一行:一个数,表示答案除以999911659的余数。
【数据规模】
10%的数据中,1 <= N <= 50;
20%的数据中,1 <= N <= 1000;
40%的数据中,1 <= N <= 100000;
100%的数据中,1 <= G <= 1000000000,1 <= N <= 1000000000。
此题用到了NOIP数论$\frac{2}{3}\qquad$的知识。
有费马小定理,Lucas定理,龟速幂,线性推逆元,扩展GCD,中国剩余定理,分解质因数的内容,一个一个来。
题目显然是让我们求G∑d|n Cdn mod P
因为P是一个质数,显然费马小定理成立$a^{p-1}$ ≡ 1
之后G上面的数可以化成∑d|n Cdn(mod P-1)
999911658=2 $\times$ 3 $\times$ 4679 $ \times $ 45617.
可以一层扩展Lucas,用中国剩余定理扩展之后合并,需要线性推逆元和扩展GCD。
之后分解质因数,龟速幂就好了!
#include<cstdio>
#define mod 999911659
#define N 50000
typedef long long ll;
ll in[5]={0,2,3,4679,35617};
ll M[N+2];
ll a[N+2];
ll n,G;
ll fac[N+2][5];
ll inv[N+2][5];
ll m=mod-1;
ll div[N+2];
ll idx;
ll ans2;
void init()
{
for(int j=1;j<=4;j++)
{
fac[0][j]=1;
inv[in[j]-1][j]=in[j]-1;
for(int i=1;i<=in[j];i++)
fac[i][j]=(fac[i-1][j]*i)%in[j];
for(int i=in[j]-2;i>=0;i--)
inv[i][j]=(inv[i+1][j]*(i+1))%in[j];
}
}
ll pow(ll x,ll y)
{
ll ans3=1;
while(y)
{
if(y&1)
ans3=(ans3*x)%mod;
x=(x*x)%mod;
y/=2;
}
return ans3;
}
ll lucas(ll n,ll m,ll i)
{
if(n<m)
return 0;
if(n<in[i]&&m<in[i])
return fac[n][i]*inv[m][i]%in[i]*inv[n-m][i]%in[i];
else
return lucas(n/in[i],m/in[i],i)%in[i]*lucas(n%in[i],m%in[i],i)%in[i];
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;
y=0;
return;
}
exgcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-a/b*y;
return;
}
ll China()
{
ll ans=0,x,y;
for(int i=1;i<=4;i++)
{
M[i]=m/in[i];
exgcd(M[i],in[i],x,y);
ans=(ans+a[i]*x*M[i])%m;
}
return (ans+m)%m;
}
int main()
{
scanf("%lld%lld",&n,&G);
if(G==mod)
{
puts("0");
return 0;
}
init();
div[++idx]=1;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
div[++idx]=i;
if((i*i)!=n)
div[++idx]=n/i;
}
}
div[++idx]=n;
for(int i=1;i<=idx;i++)
{
for(int j=1;j<=4;j++)
a[j]=lucas(n,div[i],j);
ans2=(ans2+China())%m;
}
ll ans=pow(G,ans2)%mod;
printf("%lld",ans);
}