CodeForces 990C Bracket Sequences Concatenation Problem

Posted fang-hao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces 990C Bracket Sequences Concatenation Problem相关的知识,希望对你有一定的参考价值。

题目链接

luogu &  CodeForces

 

题目描述

A bracket sequence is a string containing only characters "(" and ")".

A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters "1" and "+" between the original characters of the sequence. For example, bracket sequences "()()", "(())" are regular (the resulting expressions are: "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

You are given nn bracket sequences s1,s2,,sns1,s2,…,sn. Calculate the number of pairs i,j(1i,jn)i,j(1≤i,j≤n) such that the bracket sequence si+sjsi+sj is a regular bracket sequence. Operation ++ means concatenation i.e. "()(" + ")()" = "()()()".

If si+sjsi+sj and sj+sisj+si are regular bracket sequences and iji≠j, then both pairs (i,j)(i,j) and (j,i)(j,i) must be counted in the answer. Also, if si+sisi+si is a regular bracket sequence, the pair (i,i)(i,i) must be counted in the answer.

 

题目翻译(摘自luogu)

给出n个字符串,保证只包含‘(‘和‘)‘,求从中取2个字符串链接后形成正确的括号序列的方案数(每个串都可以重复使用)(像‘()()‘和‘(())‘这样的都是合法的,像‘)(‘和‘(‘这样的是不合法的)

输入:

第一行一个整数n

第二行到第n+1行每行一个字符串

输出:

方案数

感谢@zhaotiensn 提供翻译

 

 

解题思路

当然,首先能想到的就是n^2枚举,然后再O(len)进行判断,显然T到飞起??

然后我们想一想,先去掉O(len)的检验,这个套在n^2里实在是太过分了qwq

对于每一个串,里面有一些括号是可以直接匹配上的,那么我们先把他们处理出来,这样我们就不需要检验那么长了。  然后我们再想想,我们从一个串的左向右扫一遍,遇到‘)’就找上一个没有匹配的‘(’,然后把他们进行匹配,那么最后可能还剩下一些‘(’或‘)’没有办法进行匹配,我们用 l 表示没有匹配的‘(’的个数,r 表示为匹配的‘)’的个数。

 

 

那么,如果 l 和 r 都不等于零,那么这一个串显然是废的,因为你顶多在左边或者右边加一个串,匹配掉一个方向的括号,不可能消掉两边的括号。

相反的,如果 l 和 r 都等于零,那么拥有这些性质的串相互乱放都是可以的 ,比如串A和串B满足这个性质,则A+B和B+A都是合法的。 如果有zer个这样的串,那就有zer^2种组合方法。

如果一个串的 l 等于零,r不等于零,那么它和另一个r=0 且l等于它的r串就可以组合成一个完整的串。

 

这样记录一下l和r,整个扫一遍就OK了。

 

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int n;
 7 char s[300050];
 8 int totl[300050],totr[300050];
 9 int zer;
10 int main(){
11     cin>>n;
12     for(register int i=1;i<=n;i++){
13         scanf("%s",s);
14         int len=strlen(s),l=0,r=0;
15         for(register int j=0;j<len;j++){
16             if(s[j]==)&&!l)r++;
17             else if(s[j]==))l--;
18             else if(s[j]==()l++;
19         }
20         if(!l&&!r)zer++;
21         else if(!l)totr[r]++;
22         else if(!r)totl[l]++;
23     }
24     long long ans=0;
25     for(register int j=1;j<=300000;j++){
26         ans+=(long long)totr[j]*totl[j];
27     }
28     ans+=(long long)zer*zer;
29     cout<<ans<<endl;
30 }

 

以上是关于CodeForces 990C Bracket Sequences Concatenation Problem的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1015F Bracket Substring

CodeForces 990C

# codeforces 1272 F. Two Bracket Sequences(三维dp + bfs)

Codeforces 990C

code forces 990C

CodeForces - 5C Longest Regular Bracket Sequence