NOIP2016提高A组模拟9.17小a的强迫症

Posted 无尽的蓝黄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP2016提高A组模拟9.17小a的强迫症相关的知识,希望对你有一定的参考价值。

题目

技术分享图片

分析

题目要求第i种颜色的最后一个珠子要在第i+1种颜色的最后一个珠子之前,
那么我们从小到大枚举做到第i种,把第i种的最后一颗珠子取出,将剩下的\(num(i)-1\)个珠子插入已排好的前i-1种中,再将取出的珠子放在最后一个。
每次求出将剩下的\(num(i)-1\)个珠子插入已排好的前i-1种中的方案数,将它乘以ans。
对于每个i的方案数可以用隔板问题来求。
但是,在比赛上,我忘了隔板问题,于是再枚举个j,将已经排好的珠子分成j份,将要放进去的的\(num(i)-1\)个珠子找出j个空位(包括头和尾),将这j份珠子放入j个空位。
结果搞了半天,唉,说多了都是泪啊。。。

注意预处理阶乘,除法用逆元。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=998244353;
const long long N=100005;
using namespace std;
long long jc[N*10],a[N],sum[N],n,m,ans,ny[N*10];
long long c(long long m1,long long n1)
{
    return jc[m1]*ny[n1]%mo*ny[m1-n1]%mo;
}
long long mi(long long x,long long y)
{
    long long sum=1;
    while(y)
    {
        if(y&1) sum=sum*x%mo; 
        x=x*x%mo;
        y/=2;
    }
    return sum;
}
int main()
{
    jc[0]=1;
    for(long long i=1;i<=N*5-1;i++) jc[i]=jc[i-1]*i%mo;
    for(long long i=0;i<=N*5-1;i++) ny[i]=mi(jc[i],mo-2);
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum[i]=a[i]+sum[i-1];
    }
    ans=1;
    for(int i=2;i<=n;i++)
    {
        long long k=0;
        for(long long j=1;j<=a[i] && j<=sum[i-1];j++)
        {
            k=(k+c(a[i],j)*((j==1)?1:c(sum[i-1]-1,j-1))%mo)%mo;
        }
        ans=(ans*k)%mo;
    }
    cout<<ans;
}

以上是关于NOIP2016提高A组模拟9.17小a的强迫症的主要内容,如果未能解决你的问题,请参考以下文章

NOIP2016提高A组模拟9.17总结

NOIP2016提高A组模拟9.17数格子

Jzoj4742NOIP2016提高A组模拟9.2快速幂单峰

NOIP2016提高A组模拟10.15总结

NOIP2016提高A组模拟8.14总结

NOIP2016提高A组模拟8.15Throw