我们枚举每两个字符的空档,统计一个空档左边有 \(l\) 个左括号,

右边有 \(r\) 个右括号,左边有 \(u\) 个问号,右边有 \(v\) 个问号。

则对于 \(p\) 的答案 \(ans_p\) 有:

\[ans_p=\sum\limits_{i=0}^{u}(l+i)\dbinom{u}{i}\dbinom{v}{l+i-r}
\]

解释:

对于每个左边的问号枚举有几个变成左括号,则左边有 \(l+i\) 个左括号,方案数为 \(C_{u}^{i}\) ,右边的问号显然有 \(l+i-r\) 个变成右括号,则方案数为 \(C_{v}^{l+i-r}\) 相乘后求和即可。

弱化版直接暴力加和即可。

对于加强版显然 \(n<=1e6\) 直接枚举会 \(TLE\) ,于是考虑化简。

\[ans_p=\sum\limits_{i=0}^{u}l\dbinom{u}{i}\dbinom{v}{l+i-r}+\sum\limits_{i=0}^{u}i\dbinom{u}{i}\dbinom{v}{l+i-r}
\]
\[ans_p=l\sum\limits_{i=0}^{u}\dbinom{u}{i}\dbinom{v}{v+r-l-i}+\sum\limits_{i=0}^{u}u\dbinom{u-1}{i-1}\dbinom{v}{v+r-l-i}
\]

利用范德蒙恒等式得:

\[ans_p=l\dbinom{u+v}{v-l+r}+u\dbinom{u+v-1}{r+v-l-1}
\]

于是将所有 \(ans\) 相加即可。

Code

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
namespace EMT{
typedef long long ll;typedef double db;//(double)clock() / (double)CLOCKS_PER_SEC;
#define pf printf
#define F(i,a,b) for(register int i=a;i<=b;i++)
#define D(i,a,b) for(register int i=a;i>=b;i--)
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
inline void file(){freopen("in.in","r",stdin);freopen("my.out","w",stdout);}
inline int max(int a,int b){return a>b?a:b;}inline int min(int a,int b){return a<b?a:b;}
inline void pi(int x){pf("%d ",x);}inline void pn(){pf("\n");}
const int mod=998244353,N=1e6+100;int n,a[N],b[N],c[N],ans,jc[N];char s[N];
inline int ksm(int a,int b){
int ans=1;
while(b){
if(b&1)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b>>=1;
}return ans;
}
inline int C(int n,int m){
if(n<m||m<0)return 0;
if(!m)return 1;
return (1ll*jc[n]*ksm(jc[m],mod-2)%mod)*ksm(jc[n-m],mod-2)%mod;
}
inline short main(){
scanf("%s",s+1);n=strlen(s+1);
F(i,1,n){
a[i]=a[i-1],b[i]=b[i-1],c[i]=c[i-1];
if(s[i]=='(')a[i]++;
if(s[i]==')')b[i]++;
if(s[i]=='?')c[i]++;
}jc[0]=1;
F(i,1,n)jc[i]=1ll*jc[i-1]*i%mod;
F(i,1,n-1){
int l=a[i],r=b[n]-b[i],u=c[i],v=c[n]-c[i];
(ans+=(1ll*l*C(u+v,v-l+r)%mod+1ll*u*C(u+v-1,r+v-l-1)%mod)%mod)%=mod;
}pi(ans);
return 0;
}
}
signed main(){return EMT::main();}

CF1264D2 Beautiful Bracket Sequence的更多相关文章

  1. CF1264D2 Beautiful Bracket Sequence (hard version)

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

  2. CF1264D1 Beautiful Bracket Sequence (easy version)

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

  3. Codeforces 1264D - Beautiful Bracket Sequence(组合数学)

    Codeforces 题面传送门 & 洛谷题面传送门 首先对于这样的题目,我们应先考虑如何计算一个括号序列 \(s\) 的权值.一件非常显然的事情是,在深度最深的.是原括号序列的子序列的括号序 ...

  4. UESTC 1546 Bracket Sequence

                                        Bracket Sequence Time Limit: 3000MS   Memory Limit: 65536KB   64 ...

  5. CF#138 div 1 A. Bracket Sequence

    [#138 div 1 A. Bracket Sequence] [原题] A. Bracket Sequence time limit per test 2 seconds memory limit ...

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

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

  7. 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 ...

  8. Codeforces Beta Round #5 C. Longest Regular Bracket Sequence 栈/dp

    C. Longest Regular Bracket Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.c ...

  9. (中等) UESTC 94 Bracket Sequence,线段树+括号。

    There is a sequence of brackets, which supports two kinds of operations. we can choose a interval [l ...

随机推荐

  1. ESP32 ADF windows开发环境搭建 适配ADF到ESP32A1S(转)

    搭建ESP32A1S的ADF开发环境 一,获取IDF和IDF-TOOL adf是乐鑫的音频开发框架,里面有许多乐鑫的音频开发API,同时ADF是基于IDF的.这一部分可以按照官网的教程一步一步来.官网 ...

  2. 八大排序算法~简单选择排序【记录下标k变量的作用】

    八大排序算法~简单选择排序[记录下标k变量的作用] 1,思想:打擂台法,数组中的前n-1个元素依次上擂台"装嫩",后边的元素一个挨着一个不服,一个一个上去换掉它 2,优化:通过记录 ...

  3. Python 高级特性(2)- 迭代

    前置知识 如果给定一个 list 或 tuple,我们可以通过 for 循环来遍历这个 lis t或 tuple,这种遍历我们称为迭代(Iteration) 在 Python 中,迭代是通过 for ...

  4. 线程Thread中的方法详解(二)

    1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...

  5. 前端基础js(四)

    一. js [1] html:用于显示页面 [2] css:用于描述页面的样式 [3] javaScript:用于描述页面的行为 二.js中三大部分内容 [1] 基本语法:函数.对象.事件类型(变量, ...

  6. 第一章 Vant的引入和基本使用

    Vant UI组件库基本使用 一.Vant官网 https://youzan.github.io/vant/#/zh-CN/ 二.安装Vant npm install --save vant 三.安装 ...

  7. js学习笔记之排序算法的原理及代码

    冒泡排序 比较任何两个相邻的项,如果第一个比第二个大,则交换它们 重复这样的操作,直到排序完成,具体代码如下: let arr = [67,23,11,89,45,76,56,99] function ...

  8. Xshell 打开时,初始运行卡慢优化方法

    我使用的是Xshell 6免费版,有需要的同学可以去这个地址下载:https://www.netsarang.com/download/down_form.html?code=622 一开始安装完Xs ...

  9. 实现html页面转pdf

    实现方式比较简单,使用js代码实现的. 需要引入的js: 1.jQuery.js: 2.html2canvas.js(实现方式是先将Html页面转换成image图片然后在转换为pdf,所以转换之后会有 ...

  10. Jmeter RMI 反序列化命令执行漏洞(CVE-2018-1297)

    下载ysoserial,git git clone https://github.com/frohoff/ysoserial.git cd ysoserialmvn clean package -Ds ...