小 a 的强迫症题解

题目描述

小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);
} 

猜你喜欢

转载自blog.csdn.net/sjzezwzy/article/details/80987814