【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症 题目描述 输入 输出 样例输入 样例输出 数据范围 样例解释 解法 代码 启发

【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症
题目描述
输入
输出
样例输入
样例输出
数据范围
样例解释
解法
代码
启发

【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症
题目描述
输入
输出
样例输入
样例输出
数据范围
样例解释
解法
代码
启发

输入

【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症
题目描述
输入
输出
样例输入
样例输出
数据范围
样例解释
解法
代码
启发

输出

【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症
题目描述
输入
输出
样例输入
样例输出
数据范围
样例解释
解法
代码
启发

样例输入

3
2 2 1

样例输出

3

数据范围

【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症
题目描述
输入
输出
样例输入
样例输出
数据范围
样例解释
解法
代码
启发

样例解释

【JZOJ4786】【NOIP2016提高A组模拟9.17】小a的强迫症
题目描述
输入
输出
样例输入
样例输出
数据范围
样例解释
解法
代码
启发

解法

先假定每种颜色的珠子取一个按顺序排列。
设这n个珠子就是每一种颜色的珠子的最后一个。
考虑逐个把珠子放入。
对于第i种颜色的珠子,计算有多少种摆放方式;
显然这种颜色最后的珠子前要放sum[i]-1个珠子,然后已放的有sum[i-1]个。
计算已放的珠子的位置有多少种方案,就等价于第i种珠子的摆放方案;
也即
把所有颜色珠子的摆放方案乘起来即是答案。

代码

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define ln(x,y) int(log(x)/log(y))
#define sqr(x) ((x)*(x))
using namespace std;
const char* fin="aP1.in";
const char* fout="aP1.out";
const ll inf=0x7fffffff;
const ll maxn=100007,maxm=5*maxn,mo=998244353;
ll n,i,j,k,ans;
ll a[maxn],sum[maxn];
ll fact[maxm];
ll qpower(ll a,ll b){
    ll c=1;
    while (b){
        if (b&1) c=(c*a)%mo;
        a=(a*a)%mo;
        b>>=1;
    }
    return c;
}
ll niyuan(ll v){
    return qpower(v,mo-2);
}
ll c(ll m,ll n){
    return fact[n]*niyuan(fact[m]*fact[n-m]%mo)%mo;
}
int main(){
    scanf("%d",&n);
    for (i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
    fact[0]=1;
    for (i=1;i<=sum[n];i++) {
        fact[i]=fact[i-1]*i%mo;
    }
    ans=1;
    for (i=1;i<=n;i++){
        ans=(ans*c(sum[i-1],sum[i]-1))%mo;
    }
    printf("%lld",ans);
    return 0;
}

启发

求满足条件的排列,可以先摆放满足条件,再逐个加入元素。