Codeforces 题面传送门 & 洛谷题面传送门

首先对于这样的题目,我们应先考虑如何计算一个括号序列 \(s\) 的权值。一件非常显然的事情是,在深度最深的、是原括号序列的子序列的括号序列中,必定存在一个满足前面只由一段左括号,后面只由一段右括号组成,因此我们考虑枚举这中间位置在原括号序列中对应哪个位置,那么假设这个断点位于 \(i\) 和 \(i+1\) 之间,我们设 \(i\) 及之前有 \(x\) 个左括号,\(i+1\) 及之后有 \(y\)​​ 个右括号,那么显然以这个位置为端点的括号序列的深度就是 \(\min(x,y)\),注意到这里涉及一个 \(\min\),一脸不好直接维护的样子,不过注意一件事情,那就是你这个 \(i\) 每往后移一格,\(x-y\) 就会恰好增加 \(1\)​,也就是说必然恰好存在一个断点满足 \(x=y\),在此之前,\(x<y\)​,因此 \(\min(x,y)=x\),在此之后,\(x>y\),因此 \(\min(x,y)=y\),又因为 \(x\) 随 \(i\) 的增大单调不增,\(y\)​ 随 \(i\) 的增大单调不降,因此在这个断点前必然有 \(\min(x,y)<\) 断点处的 \(x\),在这个断点之后必然有 \(\min(x,y)>\) 断点处的 \(x\),因此这个断点处的 \(x\)​​ 就是该括号序列所有由一段左括号+一段右括号组成的合法括号序列中,深度最大的那一个,也就是说:

Conclusion. 一个括号序列的权值,等于其所有相邻位置 \(i,i+1\) 中,满足 \(i\) 及之前左括号个数等于 \(i+1\) 之后的右括号个数的 \(i\) 之前的左括号个数。

接下来此题就变成一个组合数学问题了,考虑枚举这个断点 \(i\),假设 \(i\) 前面问号个数为 \(a\),左括号个数为 \(b\),\(i+1\) 后面问号个数为 \(c\),右括号个数为 \(d\),那么这个点的贡献为:

\[\sum\limits_{i=0}^a(i+b)\dbinom{a}{i}\dbinom{c}{i+b-d}
\]

然后括号拆拆,组合恒等式推推:

\[\begin{aligned}
&\sum\limits_{i=0}^a(i+b)\dbinom{a}{i}\dbinom{c}{i+b-d}\\
=&\sum\limits_{i=0}^ai\dbinom{a}{i}\dbinom{c}{i+b-d}+b\sum\limits_{i=0}^a\dbinom{a}{i}\dbinom{c}{i+b-d}\\
=&\sum\limits_{i=0}^aa\dbinom{a-1}{i-1}\dbinom{c}{i+b-d}+b\sum\limits_{i=0}^a\dbinom{a}{i}\dbinom{c}{i+b-d}\\
=&a\sum\limits_{i=0}^a\dbinom{a-1}{a-i}\dbinom{c}{i+b-d}+b\sum\limits_{i=0}^a\dbinom{a}{a-i}\dbinom{c}{i+b-d}\\
=&a\dbinom{a-1+c}{a+b-d}+b\dbinom{a+c}{a+b-d}
\end{aligned}
\]

预处理一下简单算算即可。

const int MAXN=1e6;
const int MOD=998244353;
char s[MAXN+5];int n;
int fac[MAXN*2+5],ifac[MAXN*2+5];
void init_fac(int n){
for(int i=(fac[0]=ifac[0]=ifac[1]=1)+1;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i]*ifac[i-1]%MOD;
}
int binom(int x,int y){
if(x<0||y<0||x<y) return 0;
return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
int main(){
scanf("%s",s+1);n=strlen(s+1);init_fac(MAXN+5);int s1=0,s2=0,ans=0;
for(int i=1;i<=n;i++) s1+=(s[i]==')'),s2+=(s[i]=='?');
for(int i=1,x=0,l=0,c=0;i<=n;i++){
x+=(s[i]=='?');l+=(s[i]=='(');c+=(s[i]==')');int y=s2-x,r=s1-c;
ans=(ans+1ll*l*binom(x+y,y+r-l)+1ll*x*binom(y+x-1,y-l+r-1))%MOD;
} printf("%d\n",ans);
return 0;
}

Codeforces 1264D - Beautiful Bracket Sequence(组合数学)的更多相关文章

  1. CodeForces 670E Correct Bracket Sequence Editor(list和迭代器函数模拟)

    E. Correct Bracket Sequence Editor time limit per test 2 seconds memory limit per test 256 megabytes ...

  2. Codeforces 670E - Correct Bracket Sequence Editor - [线段树]

    题目链接:https://codeforces.com/contest/670/problem/E 题意: 给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号). 有如下操作: 1.往 ...

  3. Codeforces 670E - Correct Bracket Sequence Editor - [链表]

    题目链接:https://codeforces.com/contest/670/problem/E 题意: 给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号). 有如下操作: 1.往 ...

  4. Codeforces 670E - Correct Bracket Sequence Editor - [对顶栈]

    题目链接:https://codeforces.com/contest/670/problem/E 题意: 给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号). 有如下操作: 1.往 ...

  5. CodeForces 670E Correct Bracket Sequence Editor

    链表,模拟. 写一个双向链表模拟一下过程. #pragma comment(linker, "/STACK:1024000000,1024000000") #include< ...

  6. CF1264D2 Beautiful Bracket Sequence

    我们枚举每两个字符的空档,统计一个空档左边有 \(l\) 个左括号, 右边有 \(r\) 个右括号,左边有 \(u\) 个问号,右边有 \(v\) 个问号. 则对于 \(p\) 的答案 \(ans_p ...

  7. CF1264D2 Beautiful Bracket Sequence (hard version)

    考虑\(D1\)的\(O(n^2)\),我们直接进行组合处理. 考虑在\(p\)这个位置,左边有\(l\)个(,右边有\(r\)个),左边有\(l\)个问号,右边有\(r\)个问号. 这个位置的贡献为 ...

  8. CF1264D1 Beautiful Bracket Sequence (easy version)

    考虑在一个确定的括号序列中,我们可以枚举中间位置,按左右最长延伸出去的答案计算. 我们很自然的思考,我们直接维护左右两边,在删除一些字符后能够延伸的最长长度. 我们设\(f_{i,j}\)为\(i\) ...

  9. Educational Codeforces Round 4 C. Replace To Make Regular Bracket Sequence 栈

    C. Replace To Make Regular Bracket Sequence 题目连接: http://www.codeforces.com/contest/612/problem/C De ...

随机推荐

  1. python pip使用国内镜像安装第三方库:命令行或PyCharm

    python pip使用国内镜像安装第三方库:命令行或PyCharm 转载: https://blog.csdn.net/lly1122334/article/details/80646996

  2. 关于takin-data,你想知道的都在这里(二)trace日志篇

    相信大家在使用takin的过程中都见到过压测过程中实时展示的请求流量明细和请求详情了吧,像这样: 还有这样: 这样的请求流量明细和调用链详情是怎么实现的呢,今天就带大家探究下. 在前面的启动命令篇(h ...

  3. Asp.net Core C#进行筛选、过滤、使用PredicateBuilder进行动态拼接lamdba表达式树并用作条件精准查询,模糊查询

    在asp.net core.asp.net 中做where条件过滤筛选的时候写的长而繁琐不利于维护,用PredicateBuilder进行筛选.过滤.LInq配合Ef.core进行动态拼接lamdba ...

  4. c语言编程基础入门必备知识

    数据类型 基本数据类型 类型名称说明char字符类型存放字符的ASCII码int整型存放有符号整数short短整型存放有符号整数long长整型存放有符号整数long long存放有符号整数float单 ...

  5. stm32f103中断学习总结

    一.NVIC 介绍 NVIC 英文全称是 Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于 M3 内核的一个外设,控制着芯片的中断相关功 ...

  6. 21.7.31 test

    \(NOIP\) 测试 好久没有这种感觉能阿克的冲动了!但还是挂了分 T1 WOJ2608(模拟,拓扑排序) 签到题,直接模拟,有点像拓扑排序. 要给点打标记不然可能被某次操作中弹出多次该点导致WA ...

  7. 面试官问:说说你对Java函数式编程的理解

    常见的面试问题 总结一下,在Java程序员的面试中,经常会被问到类似这样的问题: Java中的函数式接口是什么意思? 注解 @FunctionalInterface 的作用是什么? 实现一个函数式接口 ...

  8. hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

    题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个 ...

  9. 记录一次因subprocess PIPE 引起的线上故障

    sence:python中使用subprocess.Popen(cmd, stdout=sys.STDOUT, stderr=sys.STDERR, shell=True) ,stdout, stde ...

  10. 区块链开发学习第三章:私有链上部署helloBlockchain简单合约

    前面讲了部署私有链以及新增账户,现在进行到了部署合约了,此操作真是踩了无数无数无数的坑,到写文章为止确实是已经部署好了,但是还有些坑是还没有解决的! 一.Solidity编译器 开始的时候用的http ...