- 在钦定K位被“碾压”的同学之后,直接DP无法保证剩下的N-K-1位同学都不被“碾压”,因此我们只能统计出被碾压的同学数不小于K的情况。然而,这样做依然会导致大于K的情况被算重,所幸算重的次数是可预知的,所以我们可以通过容斥的方法排除重复的情况,得到最终的答案
- lagrange插值优化:最高项n-1次,和n次,需要n+1个点确定
#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int u[105],r[105];
long long g[105][105],h[105];
int power(int n,int p)
{if(p==0){return 1;}long long tmp=power(n,p/2);if(p%2==1){return tmp*tmp%mod*n%mod;}return tmp*tmp%mod;
}
long long jc[1000005],jcinv[1000005];
void pre()
{jc[0]=1;for(int i=1;i<=1000000;i++){jc[i]=jc[i-1]*i%mod;}jcinv[1000000]=power(jc[1000000],1000000005);for(int i=1000000-1;i>=0;i--){jcinv[i]=jcinv[i+1]*(i+1)%mod;}
}
long long c(int n,int m)
{if(m>n){return 0;}return jc[n]*jcinv[m]%mod*jcinv[n-m]%mod;
}
int n,m,k;
int y[1000005];
long long s[1000005];
long long t[1000005];
long long lagrange(int m,int k)
{s[0]=1;for(int i=1;i<=m;i++){s[i]=s[i-1]*(k-i)%mod;}t[m+1]=1;for(int i=m;i>=1;i--){t[i]=t[i+1]*(k-i)%mod;}long long ans=0;for(int i=1;i<=m;i++){long long p=s[i-1]*t[i+1]%mod,q=jc[m-i]*jc[i-1]%mod;if((m-i)%2==1){q=-q;}ans=(ans+y[i]*p%mod*power(q,1000000005)%mod)%mod;}return ans;
}
void dp()
{for(int k=n-1;k>=1;k--){if(n-*max_element(r+1,r+m+1)<k){continue;}g[k][0]=1;for(int i=1;i<=m;i++){g[k][i]=0;for(int j=1;j<=min(n+1,u[i]);j++){(g[k][i]+=1ll*power(j,n-r[i])%mod*power(u[i]-j,r[i]-1)%mod)%=mod;y[j]=g[k][i];}if(u[i]>n+1){g[k][i]=lagrange(n+1,u[i]);}g[k][i]=g[k][i]*g[k][i-1]%mod*c(n-k-1,r[i]-1)%mod;}h[k]=g[k][m]*c(n-1,k)%mod;for(int i=k+1;i<=n-1;i++){h[k]=(h[k]-h[i]*c(i,k)%mod)%mod;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);pre();cin>>n>>m>>k;for(int i=1;i<=m;i++){cin>>u[i];}for(int i=1;i<=m;i++){cin>>r[i];}dp();cout<<(h[k]+mod)%mod<<endl;return 0;
}