刚学splay,过样例但是报灵求调
查看原帖
刚学splay,过样例但是报灵求调
353976
Yuzu_Soft楼主2024/3/25 20:58

rt,思路就是维护当前区间未被匹配的左右括号数qwq

#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
int n,q;
char a[100005];
int decode(char c)
{
	if(c=='(')return 1;
	if(c==')')return 2;
	if(c=='?')return 0;
	assert(false);
	return -1;
}
int inv(int x)
{
	if(x==1)return 2;
	if(x==2)return 1;
	if(x==0)return 0;
	assert(false);
	return -1;
}
pii getpii(int x,int y=1)
{
	if(x==1)return{0,y};
	if(x==2)return{y,0};
	return{0,0};
}
pii mg(pii x,pii y)
{
	pii z;
	z.first=x.first;
	z.second=y.second;
	if(x.second<y.first)z.first+=y.first-x.second;
	else z.second+=x.second-y.first;
	return z;
}
int calc(pii x)
{
	if(x.first>x.second)swap(x.first,x.second);
	return 2*x.first+(x.second-x.first)/2;
}
struct spaly
{
	struct node
	{
		int val,invval;
		int ch[2],fa,siz;
		int settag;
		bool revtag;
		bool invtag;

		pii br,invbr;
		node(){val=invval=ch[0]=ch[1]=fa=siz=settag=revtag=invtag=br.first=br.second=invbr.first=invbr.second=0;}
	}tr[100005];
	int rt,sz;
	int get(int x){return tr[tr[x].fa].ch[1]==x;}
	void pushrevtag(int x)
	{
		swap(tr[x].ch[0],tr[x].ch[1]);
		swap(tr[x].br.first,tr[x].invbr.second);
		swap(tr[x].invbr.first,tr[x].br.second);
		tr[x].revtag^=1;
	}
	void pushsettag(int x,int y)
	{
		tr[x].settag=y;
		tr[x].val=y;
		tr[x].invval=inv(tr[x].val);
		tr[x].br=getpii(tr[x].val,tr[x].siz);
		tr[x].invbr=getpii(tr[x].invval,tr[x].siz);
		tr[x].revtag=tr[x].invtag=0;
	}
	void pushinvtag(int x)
	{
		swap(tr[x].br,tr[x].invbr);
		swap(tr[x].val,tr[x].invval);
		tr[x].invtag^=1;
	}
	void pushdown(int x)
	{
		if(!x)return; 
		if(tr[x].settag)
		{
			if(tr[x].ch[0])pushsettag(tr[x].ch[0],tr[x].settag);
			if(tr[x].ch[1])pushsettag(tr[x].ch[1],tr[x].settag);
			tr[x].settag=0;
		}
		if(tr[x].invtag)
		{
			if(tr[x].ch[0])pushinvtag(tr[x].ch[0]);
			if(tr[x].ch[1])pushinvtag(tr[x].ch[1]);
			tr[x].invtag=0;
		}
		if(tr[x].revtag)
		{
			if(tr[x].ch[0])pushrevtag(tr[x].ch[0]);
			if(tr[x].ch[1])pushrevtag(tr[x].ch[1]);
			tr[x].revtag=0;
		}
	}
	void pushup(int x)
	{
		tr[x].siz=1;
		tr[x].br=getpii(tr[x].val);
		tr[x].invbr=getpii(tr[x].invval);
		if(tr[x].ch[0])tr[x].siz+=tr[tr[x].ch[0]].siz,tr[x].br=mg(tr[tr[x].ch[0]].br,tr[x].br),tr[x].invbr=mg(tr[tr[x].ch[0]].invbr,tr[x].invbr);
		if(tr[x].ch[1])tr[x].siz+=tr[tr[x].ch[1]].siz,tr[x].br=mg(tr[x].br,tr[tr[x].ch[1]].br),tr[x].invbr=mg(tr[x].invbr,tr[tr[x].ch[1]].invbr);
	}
	void rotate(int x)
	{
		int f=tr[x].fa,ff=tr[f].fa;
		int g=get(x),gg=get(f);
		pushdown(f);
		pushdown(x);
		tr[f].ch[g]=tr[x].ch[g^1];
		tr[tr[f].ch[g]].fa=f;
		tr[x].ch[g^1]=f;
		tr[f].fa=x;
		tr[x].fa=ff;
		if(ff)tr[ff].ch[gg]=x;
		pushup(f);
		pushup(x);
	}
	void splay(int x,int to=0)
	{
		for(int f;(f=tr[x].fa)!=to;rotate(x))
			if(tr[f].fa!=to)
				if(get(x)==get(f))rotate(f);
				else rotate(x);
		if(!to)rt=x;
	}
	int build(int l,int r,int f)
	{
		if(l>r)return 0;
		int mid=l+r>>1,x=++sz;
		tr[x].fa=f;
		tr[x].val=decode(a[mid]);
		tr[x].invval=inv(tr[x].val);
		tr[x].revtag=tr[x].settag=0;
		tr[x].ch[0]=build(l,mid-1,x);
		tr[x].ch[1]=build(mid+1,r,x);
		pushup(x);
		return x;
	}
	void build(int l,int r){rt=build(l,r,0);}
	int find(int x)
	{
		int pos=rt;
		while(1)
		{
			pushdown(pos);
			if(x<=tr[tr[pos].ch[0]].siz)
			{
				pos=tr[pos].ch[0];
				continue;
			}
			x-=tr[tr[pos].ch[0]].siz;
			if(x==1)return pos;
			x--;
			pos=tr[pos].ch[1];
		}
	}
	void change_replace(int l,int r,int x)
	{
		int u=find(l),v=find(r+2);
		splay(u);
		splay(v,u);
		int t=tr[v].ch[0];
		
		
		pushsettag(t,x);
	}
	void change_swap(int l,int r)
	{
		int u=find(l),v=find(r+2);
		splay(u);
		splay(v,u);
		int t=tr[v].ch[0];
		
		
		pushrevtag(t);
	}
	void change_inverse(int l,int r)
	{
		int u=find(l),v=find(r+2);
		splay(u);
		splay(v,u);
		int t=tr[v].ch[0];
		
		
		pushinvtag(t);
	}
	int query(int l,int r)
	{
		int u=find(l),v=find(r+2);
		splay(u);
		splay(v,u);
		int t=tr[v].ch[0];
		
		
		return calc(tr[t].br);
	}
}akari;
char s[10];
int main()
{
//	freopen("tat.in","r",stdin);
	scanf("%d%d",&n,&q);
	scanf("%s",a+2);
	a[1]=a[n+2]='?';
	akari.build(1,n+2);
	for(int x,y,i=1;i<=q;i++)
	{
		scanf("%s%d%d",s,&x,&y);
		if(s[0]=='R')scanf("%s",s),akari.change_replace(x,y,decode(s[0])); 
		else if(s[0]=='S')akari.change_swap(x,y);
		else if(s[0]=='I')akari.change_inverse(x,y);
		else printf("%d\n",akari.query(x,y));
	}
	return 0;
}
2024/3/25 20:58
加载中...