题解:CF1976D Invertible Bracket Sequences

可以在 cnblog 中阅读。

题意

给一个合法括号序列,问有多少区间 [l,r],使得将区间内的每个括号翻转后,括号序列仍合法。

分析

十分套路地,我们将 ( 看成 +1,将 ) 看成 1,则一个括号序列合法的充要条件是转换后的序列满足:

  1. 前缀和任意位置非负;
  2. 最后一项为 0

考虑翻转括号序列意味着什么。翻转后 +1,1 对调,为保证条件二,需要满足区间内的 +1,1 数量相等,条件一则可以通过前缀和折线图来思考。

反转后,折线图的向上变为向下,向下变为向上,实际上就是上下对称地翻转过来,对称轴就是区间的左右端点较小值。不合法当且仅当折下去低于 x 轴。

这样条件就明朗了,我们可以将前缀和丢进 map 里面,在右端点处统计对答案的贡献。最后再把折下去不合法的从 map 里扔出去。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)

void solve()
{
	string s; cin>>s;
	map<int,int> cnt;
	cnt[0]=1;
	int st=0,ans=0;
	for(char c:s)
	{
		if(c=='(') st++;
		else st--;
		ans+=cnt[st];
		cnt[st]++;
		while((*cnt.begin()).first*2<st) cnt.erase(cnt.begin());
	}
	cout<<ans<<endl;
}

signed main()
{
	IOS;
	int T; cin>>T;
	while(T--) solve();
	return 0;
}

作者:tai-chi

出处:https://www.cnblogs.com/tai-chi/p/18445424

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   tai_chi  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示