把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

题解 CF1264D1 Beautiful Bracket Sequence (easy version)

传送门

题意

一个含未知字符的括号序列,一个括号序列的权值是这个括号序列的最大深度。问所有可能的括号序列的权值和为多少。

分析

我们寻找一下深度的快速计算方式。

可以发现两个巧妙的性质。

  1. 以某一个位置分割,左边的左括号数量和右边的右括号数量的较小值就是这个位置的最大延伸深度。
  2. 由于我们的全局最大深度就是所有位置的最大延伸深度的最大值,此时,我们可以发现,此时,我们左边的左括号数应当等于右边右括号的数量。

证明:

  1. 将左边的右括号全删,右边的左括号全删,显然最优。
  2. 首先,左侧左括号的数量是一个单调递增的函数,右侧右括号的数量是一个单调递减的函数,我们的最大延伸深度就是两个函数的较下的那条线,并且总有一边会变化,且只变化 1,因此,相等处即为最大值。

然后处理问号,我们从性质 2 出手,枚举最大值的分割点,然后再枚举深度,于是就知道了左边的问号有多少个变成左括号,简单的组合就好了。

时间复杂度:O(n2)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6+5;
const int MOD = 998244353;
inline int poww(int x,int y) {
int res=1;
while(y) {
if(y&1) res=res*x%MOD;
x=x*x%MOD;
y>>=1;
}
return res;
}
int n, m,ans;
char s[N];
int L[N],R[N],qz[N],hz[N],fac[N],inv[N],inf[N];
inline void ADD(int &u,int v) {u=(u+=v)>=MOD?u-MOD:u;}
inline int C(int n,int m) {
if(n<m) return 0;
return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}
signed main() {
scanf("%s",s+1),n=strlen(s+1);
fac[0]=inf[1]=inv[1]=inv[0]=1;
for(int i=1; i<N; ++i) fac[i]=fac[i-1]*i%MOD;
for(int i=2; i<N; ++i) inf[i]=(MOD-(int)(MOD/i))*inf[MOD%i]%MOD;
for(int i=2; i<N; ++i) inv[i]=inv[i-1]*inf[i]%MOD;
for(int i=1; i<=n; ++i) L[i]=L[i-1]+(s[i]=='('),qz[i]=qz[i-1]+(s[i]=='?');
for(int i=n; i>=1; --i) R[i]=R[i+1]+(s[i]==')'),hz[i]=hz[i+1]+(s[i]=='?');
for(int i=1; i<n; ++i) {
int cntl=L[i],cntr=R[i+1],yl=qz[i],yr=hz[i+1];
for(int j=max(cntl,cntr); j<=min(i,n-i); ++j) ADD(ans,j*C(yl,j-cntl)%MOD*C(yr,j-cntr)%MOD);
}
cout<<ans;
return 0;
}
posted @   djh0314  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示