1 条题解
-
1
#include<bits/stdc++.h> using namespace std; const int P=1e9+7; int n,m,k; int U[105],R[105]; long long Pow(long long a,long long p) { long long ret=1; for(; p; p>>=1,a=a*a%P)if(p&1)ret=ret*a%P; return ret; } //各种预处理 long long C[105][105],Pw[105][105];//在暴力G函数中用的乘方也可以预处理 long long Fact[105],Inv[105]; void Init() { for(int i=1; i<=100; i++) for(int j=0; j<=i; j++) if(j==0||j==i)C[i][j]=1; else C[i][j]=(C[i-1][j-1]+C[i-1][j])%P; Fact[0]=1; for(int i=1; i<=100; i++)Fact[i]=Fact[i-1]*i%P,Inv[i]=Pow(i,P-2); for(int i=0; i<=100; i++) { Pw[i][0]=1; for(int j=1; j<=100; j++)Pw[i][j]=Pw[i][j-1]*i%P; } } long long F(int p) {//F函数 long long Ans=1; for(int i=1; i<=m; i++)Ans=Ans*C[p][R[i]-1]%P;//暴力即可 return Ans; } long long Calc() { int tot=n-k-1; long long Ans=0; for(int i=0; i<tot; i++) { long long th=F(tot-i)*C[tot][i];//不要忘记乘组合数! if(i&1)Ans-=th;//i表示tot个人中有多少个人没有出现,故偶加奇减 else Ans+=th; Ans%=P; } Ans=(Ans+P)%P; return Ans; } long long g(int u,int a,int b) {//暴力G函数 long long ret=0; for(int i=0; i<u; i++)ret=(ret+Pw[i][a]*Pw[u-i][b])%P; return ret; } long long D[105]; long long G(int u,int a,int b) {//离散化优化G函数 long long Ans=0; long long Combination=1; for(int i=1; i<=n; i++) { D[i]=g(i,a,b); for(int j=1; j<i; j++)D[i]=(D[i]-D[j]*C[i][j])%P;//减去重复的 Combination=Combination*(u-i+1)%P*Inv[i]%P;//组合数可以递推 Ans=(Ans+D[i]*Combination)%P;//加法原理 } return (Ans+P)%P; } void Solve() { Init(); long long Ans=C[n-1][k]*Calc()%P; for(int i=1; i<=m; i++)Ans=Ans*G(U[i],R[i]-1,n-R[i])%P;//乘法原理 printf("%lld\n",Ans); } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1; i<=m; i++)scanf("%d",&U[i]); for(int i=1; i<=m; i++)scanf("%d",&R[i]); Solve(); return 0; }
- 1
信息
- ID
- 2206
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 9
- 已通过
- 2
- 上传者