2024/6/28UPD CSDN又擅自给我改VIP文章:(
题面
题目大意
对于一个长度为 2 n 2n 2n 的合法的括号串 s s s,按照如下方法构造一张无向图:
括号序列的所有位置都是无向图中的一个点。
对于该序列的任意位置 l l l,它能向另一个位置 r r r 连边当且仅当满足子串 s [ l , … , r ] s[l, \; \dots , \; r] s[l,…,r] 也是一个合法括号串。
求这张无向图的连通块个数。
输入格式
第一行包含一个整数 T ( 1 ⩽ T ⩽ 1 0 5 ) T \; (1 \leqslant T \leqslant 10^5) T(1⩽T⩽105) 表示测试样例组数。
对于每组测试样例,第一行包含一个整数 n ( 1 ⩽ n ⩽ 1 0 5 ) n \; (1 \leqslant n \leqslant 10^5) n(1⩽n⩽105) 表示序列长度为 2 n 2n 2n。
接下来的一行包含一个长度为 2 n 2n 2n 的合法括号串。
输出格式
对于每组测试样例,包含一个整数表示该串构造的无向图的连通块数。
T r a n s l a t e d b y Z i g h Translated \; by \; Zigh TranslatedbyZigh
分析
一看到括号序列,我们第一反应一定是用栈来维护,那么这和这道题有什么关系呢?
首先我们观察下面这个括号串:
所有的
t
o
p
=
k
top = k
top=k 的左括号只会向
t
o
p
=
k
−
1
top = k - 1
top=k−1 的右括号连边,并且他们之间不能存在任何一个
t
o
p
<
k
−
1
top < k - 1
top<k−1 的右括号,否则他们会被隔断, 如下图:
上图中的那条蓝色边就不应该存在,因为他们之间有一个
0
0
0 阻隔。
也就是说,我们把右括号的 t o p top top 单独拎出来看,我们会发现连续的一段相等的会形成一个连通块 ( 形如 AAAAAA ),或者一段连续相等的中间夹着一些比他大的会形成一个连通块 ( 形如 AAABBBAA 其中 A < B)。通过观察我们可以发现,接下来将会形成一个新的连通块有且仅当 t o p i > t o p i + 1 top_i > top_{i + 1} topi>topi+1。那我们只需要数出这样的对数即可,最后别忘了加上最外面一层的 1 1 1。
代码
//省略快读和头文件
int T;
int n;
char str[MAXN];
int a[MAXN], cnt = 0;
int tp = 0;
int ans = 0;
int main()
{
T = inpt();
// scanf("%d", &T);
while(T--) {
ans = 0;
tp = 0;
cnt = 0;
n = inpt();
scanf("%s", str + 1);
for(int i = 1; i <= 2 * n; i++) {
if(str[i] == '(') {
tp++;
}else {
tp--;
a[++cnt] = tp;
}
}
for(int i = 1; i < cnt; i++) {
if(a[i] > a[i + 1])
ans++;
}
printf("%d\n", ans + 1);
}
return 0;
}
提醒
最后一点提醒,文件名不要直接粘贴题目名字哦,不然调试两行泪哦~
猜猜,那个题面里的 Z i g h Zigh Zigh 是谁呢Qwq