【NOIP2016提高A組模擬9.17】小a的強迫癥
阿新 • • 發佈:2018-05-17
ret include sin main img int 我們 scanf can
題目
分析
題目要求第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的強迫癥