题意太迷。。。
其实就是求n个点symmetric labeled cliquer的个数,然后取一个m次幂。
答案就是
m∑x|nn!(x!)nx(nx!)
把mod-1分解质因数,把这个数分别取模mod-1的因子,然后用CRT合并。
不过这个东西不是组合数,不能用lucas。可以先预处理阶乘,用礼物的方法做,会比lucas多个log,不过这题还挺快的。
#include <bits/stdc++.h>
using namespace std;
#define mod 999999599
#define ll long long
#define PA pair<int,int>
#define N 8100
int p[5]={2,13,5281,7283};
int n,m,T;
int a[5],jc[5][N];
int qpow(int x,int y,int md)
{
int ret=1;
while(y)
{
if(y&1)ret=(ll)ret*x%md;
x=(ll)x*x%md;y>>=1;
}
return ret;
}
void init()
{
for(int i=0;i<4;i++)
{
jc[i][0]=1;
for(int j=1;j<p[i];j++)
jc[i][j]=jc[i][j-1]*j%p[i];
}
}
void exgcd(ll &x,ll &y,int a,int b)
{
if(b==0){x=1;y=0;return;}
exgcd(y,x,b,a%b);y-=a/b*x;
}
PA get(int x,int tp,int md)
{
if(x==0)return make_pair(1,0);
int t=x/md;
PA r1=get(t,tp,md);
return make_pair(qpow(jc[tp][md-1],t,md)*
jc[tp][x-t*md]%md*r1.first%md,r1.second+t);
}
void cal(int x)
{
for(int i=0;i<4;i++)
{
PA t1=get(n,i,p[i]),t2=get(x,i,p[i]),t3=get(n/x,i,p[i]);
if(t1.second-t2.second*(n/x)-t3.second)continue;
a[i]=(a[i]+t1.first*qpow(qpow(t2.first,n/x,p[i])*t3.first%p[i],p[i]-2,p[i])%p[i])%p[i];
}
}
int CRT(int md)
{
int ret=0;
ll x,y;
for(int i=0;i<4;i++)
{
exgcd(x,y,md/p[i],p[i]);
x=(x%p[i]+p[i])%p[i];
ret=(ret+md/p[i]*x%md*a[i]%md)%md;
}
return ret;
}
int main()
{
//freopen("tt.in","r",stdin);
init();
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(int i=1;(ll)i*i<=n;i++)
if(n%i==0)
{
cal(i);
if(i*i!=n)cal(n/i);
}
printf("%d\n",qpow(m,CRT(mod-1),mod));
}
return 0;
}