题解:P13757 【MX-X17-T6】Selection
Rainbow_qwq · · 题解
先钦定前
钦定前
那么要求的问题转化为,总方案数,减去“都有等于”的方案数。
总方案数就是拆成每个位置,枚举最小值,为:
这个式子是一个关于
要减去的部分,枚举前
现在问题在于对于每个
设二元 EGF:
对两维求导,可得:
提取两边
据此递推即可
总复杂度
struct fval{
vector<modint>x,y;
void ins(modint X,modint Y){x.pb(X),y.pb(Y);}
void init(){x.clear(),y.clear();}
modint val(modint k){
int n=x.size();
modint res=0;
For(i,0,n-1){
modint s1=1,s2=1;
For(j,0,n-1)if(i!=j)s1*=(k-x[j]),s2*=(x[i]-x[j]);
res+=y[i]*s1/s2;
}
return res;
}
}F;
int n,m,k,v;
modint f[4005][4005],sum[8005];
namespace CF{
// O(k)
modint ml[maxn],mr[maxn];
modint solve(int n,int k){
if(n<=k+5){
modint zz=0;
For(i,1,n)zz+=qpow(i,k);return zz;}
For(i,0,k+4)ml[i]=mr[i]=0;
ml[0]=mr[k+3]=1;
For(i,1,k+2) ml[i]=ml[i-1]*(n-i);
Rep(i,k+2,1)mr[i]=mr[i+1]*(n-i);
modint res=0,y=0;
For(i,1,k+2){
y+=modint(i)^k;
modint a=ml[i-1]*mr[i+1];
modint b=ifac[i-1]*ifac[k+2-i];
if((k-i)&1)b=-b;
res+=y*a*b;
}
return res;
}
}
void work(int O)
{
n=read(),m=read(),k=read(),v=read();
modint res=0;
modint all=0;
F.init();
For(vv,1,n+3){
modint sv=0;
For(i,1,vv){
modint tmp=qpow(vv-i+1,k);
tmp*=(qpow(i,n-k)-qpow(i-1,n-k));
sv+=tmp;
}
// cout<<"vv,sv "<<vv<<" "<<sv.x<<"\n";
F.ins(vv,sv);
}
all=F.val(v);
// cout<<"all "<<v<<' '<<all.x<<"\n";
// For(i,1,v){
// modint tmp=qpow(v-i+1,k);
// tmp*=(qpow(i,n-k)-qpow(i-1,n-k));
// all+=tmp;
// }
res=qpow(all,m);
// cout<<"res "<<res.x<<"\n";
// need: for i,j, f[i][j]=\sum qpow(v-z,i)*qpow(z,j)
// (v+1)*f[i][j] = f[i+1][j]*(i+1) + f[i][j+1]*(j+1)
// f[i][j+1] * (j+1) =
auto calc=[&](int i,int j){
// modint tmp=0;
// For(z,1,v) tmp+=qpow(v-z+1,i)*qpow(z,j);
modint tmp=0;
For(z,1,v) tmp+=qpow(z,i);
return tmp;
};
For(i,0,n){
f[i][0]=CF::solve(v,i);
//f[i][0]=calc(i,0);
if(i==0) f[i][0]=v;
f[i][0]*=ifac[i];
// F.init();
// For(j,1,i+1){
// sum[j]=sum[j-1]+qpow(j,i);
// }
// For(j,0,i+1) F.ins(j,sum[j]);
// f[i][0]=F.val(v)*ifac[i];
// f[i][0]=calc(i,0)*ifac[i];
// cout<<"i,0 "<<i<<" "<<0<<" "<<f[i][0].x<<"\n";
}
For(j,0,n-1){
For(i,0,n){
//
f[i][j+1]=(f[i][j]*(v+1)-f[i+1][j]*(i+1));
f[i][j+1]*=iv[j+1];
// cout<<"i,j "<<i<<" "<<j+1<<" "<<f[i][j+1].x<<"\n";
}
}
For(i,1,k) For(j,1,n-k) {
modint tmp=0;
tmp=f[k-i][n-k-j];
tmp*=fac[k-i]*fac[n-k-j];
// For(z,1,v) tmp+=qpow(v-z+1,k-i)*qpow(z,n-k-j);
// cout<<"tmp "<<tmp.x<<"\n";
tmp=qpow(tmp,m);
tmp*=C(k,i)*C(n-k,j);
res-=tmp*sign(i+j);
}
res*=C(n,k);
cout<<res.x<<"\n";
}
signed main()
{
initC(5005);
int T=read();
For(_,1,T)work(_);
return 0;
}