首页 > 其他分享 >题解:CF1976D Invertible Bracket Sequences

题解:CF1976D Invertible Bracket Sequences

时间:2024-10-03 10:00:15浏览次数:6  
标签:cnt 题解 st 括号 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;
}

标签:cnt,题解,st,括号,Bracket,Sequences,序列,合法,翻转
From: https://www.cnblogs.com/tai-chi/p/18445424

相关文章

  • ZZJC新生训练赛第二场题解
    先给出比赛链接:https://ac.nowcoder.com/acm/contest/92036A小红打怪ShowCodeAclassPoint{//点类public:intx,y;Point(){}Point(intx,inty):x(x),y(y){}Pointoperator+(constPoint&P)const{returnPoint(x+P.x,y+P.y);......
  • 题解:TopCoder12316 ThreeColorability
    Vjudge可以出成《三色绘恋》背景。题意给一个格点数为\((n+1)\times(m+1)\)的网格,给格点染色,相邻的格点不能染成同样的颜色。每个格子有一条对角线的边,可选N形和Z形。现在有一个残缺的网格,存在一些格子的对角线连法不确定,构造一种字典序最小的方案使得至少存在一种染色......
  • 树上最值路径 题解
    题意简述给你一棵\(n\)个结点的树,编号为\(1\simn\),求有多少路径\(\operatorname{Path}(u\rightarrowv)\),满足\(u=\max\{x\midx\in\operatorname{Path}(u\rightarrowv)\}\),\(v=\min\{x\midx\in\operatorname{Path}(u\rightarrowv)\}\)。......
  • 题解:CF2014D Robert Hood and Mrs Hood
    差分,每次差分将\(\max(1,l-d+1)\)加\(1\),将\(r+1\)位置减\(1\)。然后前缀和求原数组,再遍历一下求最小值和最大值即可。代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ intt; cin>>t; while(t--){ intn,d,k; cin>>n>>d>>k;......
  • 题解:CF2009E Klee's SUPER DUPER LARGE Array!!!
    设\(m\)为\(a_1+\dots+a_i\),\(n\)为\(a_{i+1}+\dots+a_n\)。我们可以使用二分查找来搜索\(i\),使得\(m-n\)为最小的负数。如果我们移动到\(i+1\),则此时\(m-n\)为最小的整数。答案是两种情况下的最小绝对值。代码:#include<bits/stdc++.h>usingnamespacestd;pair<......
  • 题解:CF2009D Satyam and Counting
    比较容易观察的一道题,但是场上不开longlong见祖宗了。由于这题的\(x\)最大值比较小,所以我们可以直接存每个坐标是否有点。有两种三角形符号条件:存在两个点\((x,0),(x,1)\),可以观察到任意的其它点都可以成为第三点。有三个点为\((x,0),(x+1,1),(x+2,0)\)或\((x,1),(x+1......
  • 题解:CF2009C The Legend of Freya the Frog
    比较一眼的题目,场切了。分别考虑\(x\)和\(y\)。在\(x\)方向上我们需要的跳跃次数是\(\lceil\frac{x}{k}\rceil\),在\(y\)方向上我们需要的跳跃次数是\(\lceil\frac{y}{k}\rceil\)。考虑下面的两种情况:\(\lceil\frac{y}{k}\rceil\geq\lceil\frac{x}{k}\rceil......
  • 题解:P11137 [APC001] B - Checker
    注意到每个字符串长度相同,所以我们可以按照题意逐个遍历小K的题目和所有题库里的题目,统计相同位置字符相同的个数,如果大于\(\left\lceil\frac{k}{2}\right\rceil\),这两个题目就是重题。代码:#include<bits/stdc++.h>usingnamespacestd;boolc(stringa,stringb){in......
  • 题解:CF2014C Robin Hood in Town
    分享一种二分答案做法。先特判\(n=1\),\(n=2\),开始就有超过一半的人不高兴的情况。然后二分\(x\),计算新的和,新的平均值,如果有超过一半的人不高兴,就更新答案。代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ intt; cin>>t; while(t--){ intn; cin>>n......
  • 题解:SP7973 ACPC10E - Sometimes, a penalty is good!
    比较简单的一道数学题。思路:计算小组赛的比赛总数。longlongstage1=G*T*(T-1)/2;每组有\(T\)个队伍,每个队伍都需要与其他\(T-1\)个队伍比赛,共有\(T\cdot(T-1)\)场比赛。共有\(G\)组,因此小组赛总比赛数为\(\frac{G\cdotT\cdot(T-1)}{2}\)。计算进入......