3 D Least Cost Bracket Sequence

問題

開き括弧、閉じ括弧、および?からなる文字列が与えられる。
この文字列の?を、開き括弧に変えるコスト、閉じ括弧に変えるコストが?ごとに与えられる。


このとき、括弧の対応が正しくなる式で、コストが最も小さいものおよびそのときのコストを出力せよ。

制約条件

n≦4*10^4


Editorial見た。

方針

  • (が出てきたら深さを+1
  • )が出てきたら深さを-1

するとする。
括弧の対応づけが正しいとは、各位置における括弧の深さが0以上で、かつ文字列終了時に深さが0であることである。


priority_queueを使う。
?が出てきたら、とりあえずそこは)が出てきたものとしておき、
priority_queueに、位置およびコストa[i]-b[i]を登録しておく。


深さが負になってしまったら、最もコストが安い?を(に変える。
priority queueが空だったら、どう?に括弧を割り当てても正しい対応が作れない。

ソースコード

string in;
int n,a[50000],b[50000],m;
int pos[50000],choose[50000];
void run()
{
	cin>>in;
	n=in.size();
	rep(i,n)if(in[i]=='?'){
		cin>>a[m]>>b[m];
		pos[m++]=i;
	}
	int depth=0,k=0; ll ans=0;
	priority_queue<pi> q;
	rep(i,n){
		if(in[i]=='(')depth++;
		else if(in[i]==')')depth--;
		else{
			q.push(mp(b[k]-a[k],i));
			ans+=b[k++];
			depth--;
		}
		if(depth<0){
			if(q.empty()){
				cout<<-1<<endl; return;
			}
			choose[q.top().second]=1;
			ans-=q.top().first; q.pop(); depth+=2;
		}
	}
/*
	for(;depth<0;depth+=2){
		if(q.empty()){
			cout<<-1<<endl; return;
		}
		choose[q.top().second]=1;
		ans-=q.top().first; q.pop();
	}
*/
	if(depth!=0){
		cout<<-1<<endl; return;
	}
	cout<<ans<<endl;
	rep(i,n)if(in[i]=='?')putchar(choose[i]?'(':')');
	else putchar(in[i]);
	puts("");
}