stack(计蒜客信息学 8 月提高组模拟赛)
作者:互联网
C.stack
本问题是使用栈跳出开头是1的操作序列方案数
考虑⼀个合法的输出时如何产生的,因为开头必须为1,先指定开头的元素,将这个元素前面的元素都先放⼊栈中。
把问题转化成一个栈中已经存在一定元素求出栈序列个数。假设这个元素为第i个,那么1~i-1在栈中,1+i~n在队列中。就是转化为经典的卡特兰数:
答案为
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e6 + 10; 4 const int mod = 998244353; 5 int n, f[maxn]; 6 int fac[maxn<<1],inv[maxn<<1]; 7 int qmi(int a, int b, int m) { 8 a %= m; 9 if (!a)return 0; 10 int result = 1; 11 for (; b; a = 1ll * a * a % m, b >>= 1) 12 if (b& 1)result = 1ll * result * a % m; 13 return result; 14 } 15 int C(const int n, const int m) { 16 if (n < m)return 0; 17 return 1ll * fac[n] * inv[m] % 998244353 * inv[n - m] % 998244353; 18 } 19 int cal(int a, int b) { 20 return(1ll * C(a + 2 * b, b) - C(a + 2 * b, b - 1) + 998244353) % 998244353; 21 } 22 void init(const int n) { 23 fac[0] = 1; 24 for (int i = 1; i <= n; i++)fac[i]=1ll*fac[i-1]*i%998244353; 25 inv[n] = qmi(fac[n], 998244353 - 2, 998244353); 26 for (int i = n - 1; i >= 0; i--) 27 inv[i] = inv[i + 1] * (i + 1ll) % 998244353; 28 } 29 int main() { 30 freopen("stack.in", "r", stdin); 31 freopen("stack.out", "w", stdout); 32 scanf("%d", &n); 33 init(n << 1); 34 for (int i = 1; i <= n; i++)scanf("%d", &f[i]); 35 int ans = 0; 36 for (int i = 1; i <= n; i++) 37 if (f[i])ans=(ans+cal(i-1,n-i))%998244353; 38 cout<<ans<<endl; 39 return 0; 40 }
标签:信息学,const,int,inv,1ll,return,计蒜客,stack,998244353 来源: https://www.cnblogs.com/nancychai/p/16608347.html