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;
}