题目描述
小a是一名强迫症患者,现在他要给一群带颜色的珠子排成一列,现在有N种颜色,其中第i种颜色的柱子有num(i)个。要求排列中第i种颜色珠子的最后一个珠子,一定要排在第i+1种颜色的最后一个珠子之前。问有多少种排列珠子的方案。
输入输出格式
输入格式:
第一行一个整数N,表示珠子颜色数量 第二行N个整数,分别表示每种珠子的颜色数量
输出格式:
排列方案数,对998244353取余
输入输出样例
输入样例#1:
3
2 2 1
输出样例#1:
3
分析
我们从后往前找,对于最后一个珠子,必定是最后一种颜色,而对于最后一种颜色的其他珠子,我们可随便放,倒数第二个也是……当倒推到开头时,我们可列出此时方案数是C(a[1]+a[2]-1,a[2]-1),从前再往后推回去即可。时间:200ms。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long jc[500010],ny[500010],ans=1,n,x,qaq=0,mod=998244353;
long long power(long long x,long long y){
long long z=1;
while(y){
if(y%2)
z=z*x%mod;
y/=2;
x=x*x%mod;
}
return z;
}
long long lalala(long long n,long long m){
return jc[n]%mod*ny[n-m]%mod*ny[m]%mod;
}
int main(){
jc[1]=1;
for(int i=2;i<=500000;++i)
jc[i]=jc[i-1]*i%mod;
ny[500000]=power(jc[500000],mod-2);
for(int i=500000;i;i--)
ny[i-1]=ny[i]*i%mod;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
qaq=qaq+x-1;
ans=ans*lalala(qaq,x-1)%mod;
qaq++;
}
printf("%lld\n",ans);
}