Codeforces Round #5 C.Longest Regular Bracket Sequence

積み残し。

問題概要

括弧からなる文字列を、+と1を挿入して正しい数式にできるとき、その文字列を"regular"であるという。
例えば"(())()", "()","(()(()))"はregularであり、")(", "(()", "(()))("はregularではない。


長さ10^6以下の括弧からなる文字列が与えられる時、この文字列の連続する部分列で、regularな文字列のうち長さが最大のものについて、その長さと出現回数を求めよ。

解法

自力で解けなかったのでlaycurse先生のブログを参考に……


括弧の深さが0以下になってしまう(例:())など)とその時点でregularでなくなってしまうのはすぐにわかる。
なので、

  • それぞれの括弧の深さごとに、開始括弧の位置を覚えておき
  • 深さがdになったときにd+1の開始位置をリセットする

ような操作を繰り返していけば最大長のregularな文字列を得ることができる。

ソースコード

int idx[10000001];

void run()
{
	string str; cin>>str;
	fill_n(idx,10000001,inf);
	
	int ans=0,times=1,d=5000000;
	
	rp(i,str)
	{
		if(str[i]=='(')
		{
			d++;
			if(idx[d]==inf)idx[d]=i;
		}
		else
		{
			int tmp=i-idx[d]+1;
			if(tmp==ans)times++;
			if(tmp>ans)ans=tmp,times=1;
			idx[d+1]=inf; d--;
		}
	}
	cout<<ans<<" "<<times<<endl;
}