【题解】CF1264D2
题目大意
给定一个长度为的字符串,其中只有(, ), ?
三种字符,其中?
可以为(
或者)
对于一个括号序列,定义其权值为其通过删除字符后可以得到的合法的括号匹配的最深的深度,下面是一些括号匹配的例子:
深度为
深度为
深度为
下面这个例子是一个深度为的括号序列,当然其权值也为
深度为
您希望求出所有可能的括号序列(即问号替换后)的权值,答案对取模
题解
考虑最终对答案造成贡献的序列是什么样的,显然除了构成最深的括号子序列的括号是一一配对的,其余的问号都是左边的全是右括号,右边同理。
于是可以写出答案的式子,范德蒙德卷积化简得到最终的式子。
范德蒙德卷积应用:考虑组合意义。
考虑总贡献可以分析终态的形式,同时本题也启示对于正解的思考可以先做出最暴力的式子去化简或思考出高复杂度的方法消减不必要的时间。
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int rd(){
int f=1,j=0;
char w=getchar();
while(!isdigit(w)){
if(w=='-')f=-1;
w=getchar();
}
while(isdigit(w)){
j=j*10+w-'0';
w=getchar();
}
return f*j;
}
const int N=1000010,mod=998244353;
int n,l,r,x,y,ans;
int inv[N],fps[N];
char s[N];
inline int pw(int x,int y){
int ansn=1;
while(y){
if(y&1)ansn=ansn*x%mod;
x=x*x%mod,y/=2;
}
return ansn;
}
inline int C(int x,int y){
if(y<0||x<y)return 0;
// cout<<"cal:"<<x<<" "<<y<<":"<<fps[x]*inv[y]%mod*inv[x-y]%mod<<"\n";
return fps[x]*inv[y]%mod*inv[x-y]%mod;
}
signed main(){
scanf("%s",s+1),n=strlen(s+1);
fps[0]=inv[0]=1;
for(int i=1;i<=n;i++)fps[i]=fps[i-1]*i%mod;
inv[n]=pw(fps[n],mod-2);
for(int i=n-1;i>=1;i--)inv[i]=inv[i+1]*(i+1)%mod;
for(int i=1;i<=n;i++)r+=(s[i]==')'),y+=(s[i]=='?');
for(int i=1;i<=n;i++){
r-=(s[i]==')'),y-=(s[i]=='?');
l+=(s[i]=='('),x+=(s[i]=='?');
// cout<<i<<":"<<l<<" "<<r<<"-"<<x<<" "<<y<<":"<<x+y-1<<" "<<y-l+r-1<<" "<<C(x+y-1,y-l+r-1)<<"\n";
ans+=l*C(x+y,y+r-l)%mod+x*C(x+y-1,y-l+r-1)%mod,ans%=mod;
}
printf("%lld\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】