社区讨论

求助 过样例但0分

P3215[HNOI2011] 括号修复 / [JSOI2011] 括号序列参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@m41ginyr
此快照首次捕获于
2024/11/28 23:15
去年
此快照最后确认于
2024/11/28 23:39
去年
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,q,cnt,rt,a[N],sum[N],pmin[N],pmax[N],smin[N],smax[N],sz[N],val[N],ls[N],rs[N],num[N];
bool rev[N],flp[N];
string s;
int create(int x){
	int p=++cnt;
	a[p]=sum[p]=x;
	if(x==-1) pmin[p]=smin[p]=-1;
	else pmax[p]=smax[p]=1;
	sz[p]=1,val[p]=rand();
	return p;
}
void push_up(int p){
	sum[p]=sum[ls[p]]+sum[rs[p]]+a[p];
	sz[p]=sz[ls[p]]+sz[rs[p]]+1;
	pmin[p]=min(pmin[ls[p]],sum[ls[p]]+a[p]+pmin[rs[p]]);
	pmax[p]=max(pmax[ls[p]],sum[ls[p]]+a[p]+pmax[rs[p]]);
	smin[p]=min(smin[rs[p]],sum[rs[p]]+a[p]+smin[ls[p]]);
	smax[p]=max(smax[rs[p]],sum[rs[p]]+a[p]+smax[ls[p]]);
}
void update1(int p,int k){
	a[p]=num[p]=k,sum[p]=sz[p]*k;
	if(k==-1) pmin[p]=smin[p]=sum[p],pmax[p]=smax[p]=0;
	else pmax[p]=smax[p]=sum[p],pmin[p]=smin[p]=0;
}
void update2(int p){
	swap(ls[p],rs[p]);
	swap(pmin[p],smin[p]); swap(pmax[p],smax[p]);
	rev[p]^=1;
}
void update3(int p){
	a[p]*=-1,sum[p]*=-1,num[p]*=-1;
	swap(pmin[p],pmax[p]); pmin[p]*=-1,pmax[p]*=-1;
	swap(smin[p],smax[p]); smin[p]*=-1,smax[p]*=-1;
	flp[p]^=1;
}
void push_down(int p){
	if(num[p]){
		if(ls[p]) update1(ls[p],num[p]);
		if(rs[p]) update1(rs[p],num[p]);
		num[p]=0;
	}
	if(rev[p]){
		if(ls[p]) update2(ls[p]);
		if(rs[p]) update2(rs[p]);
		rev[p]=0;
	}
	if(flp[p]){
		if(ls[p]) update3(ls[p]);
		if(rs[p]) update3(rs[p]);
		flp[p]=0;
	}
}
void split(int p,int k,int &x,int &y){
	if(!p){
		x=y=0;
		return;
	}
	push_down(p);
	if(k<=sz[ls[p]]){
		y=p;
		split(ls[p],k,x,ls[p]);
	}
	else{
		x=p;
		split(rs[p],k-sz[ls[p]]-1,rs[p],y);
	}
	push_up(p);
}
int merge(int x,int y){
	if(!x||!y) return x+y;
	push_down(x); push_down(y);
	if(val[x]<val[y]){
		rs[x]=merge(rs[x],y);
		push_up(x);
		return x;
	}
	ls[y]=merge(x,ls[y]);
	push_up(y);
	return y;
}
void Replace(int l,int r,int k){
	int x,y,z;
	split(rt,l-1,x,y); split(y,r-l+1,y,z);
	update1(y,k);
	rt=merge(merge(x,y),z);
}
void Reverse(int l,int r){
	int x,y,z;
	split(rt,l-1,x,y); split(y,r-l+1,y,z);
	update2(y);
	rt=merge(merge(x,y),z);
}
void Flip(int l,int r){
	int x,y,z;
	split(rt,l-1,x,y); split(y,r-l+1,y,z);
	update3(y);
	rt=merge(merge(x,y),z);
}
int query(int l,int r){
	int x,y,z,ans;
	split(rt,l-1,x,y); split(y,r-l+1,y,z);
	ans=(pmax[y]+1)/2+(abs(smin[y])+1)/2;
	rt=merge(merge(x,y),z);
	return ans;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>q>>s;
	for(int i=0;i<n;i++){
		int x=(s[i]=='('?-1:1);
		rt=merge(rt,create(x));
	}
	while(q--){
		string opt;
		int l,r,x;
		cin>>opt>>l>>r;
		if(opt[0]=='R'){
			char c;cin>>c;
			x=(c=='('?-1:1);
			Replace(l,r,x);
		}
		else if(opt[0]=='S') Reverse(l,r);
		else if(opt[0]=='I') Flip(l,r);
		else cout<<query(l,r)<<"\n";
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...