相当郁闷啊,初看,题目描述简单,感觉很容易,直接由区间'('数判断,敲出来之后“意外”wrong了,当时就感觉自己2了,怎么会这么想呢。找度娘咨询了一下解题思路,原来还要记录区间左连续最值,有思路了,果断敲代码;正好刚刚做完poj3225也是一个区间合并取反操作的题,参考了一下自己的代码,很顺利的桥完了;然后各种调试,终于过了测试数据,自己也写了几组都过了;交上去又wrong了,意料之中一般都不会1A的,然后又是各种检查错误。在上一题的深远影响下,把一个判断条件弄反了,我擦,也不知道测试数据怎么就过了,太坑爹了。然后又交上去,居然又wrong了,我就去啦,怎么还这样啊,然后又是苦逼的小调,本来头就有点晕,看到一排排的字母数字,已经没什么思想了。找不出错误的滋味太不好受啊,还是躺床上想想吧,此处略去一下午,只能晚上到实验室找队友帮忙了,给他讲了一下思路,然后让他看代码,自己也在检查,自己在模拟的时候,突然发现48行的判断条件似乎也弄反了,主要还是对着上一题的代码敲猜错的,交上去终于AC了。各种感慨,各种悲剧啊,两个小错误卡了一天多,只能说自己2啦!为了避免犯同样的错误,以后坚决不轻易这样了,太让人想死了。谨以此文为戒!!!下面是ACcode代码,实在不想再花时间去优化了。
ACcode:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int size=111111;
struct Node
{
int sum;
int lazy;
int xr;
int lmax,lmin;
}tre[size<<2];
char str[size];
int Max(int a1,int a2) { return a1>a2?a1:a2; }
int Min(int a1,int a2) { return a1<a2?a1:a2; }
void pushup(int rt)
{
int r1=rt<<1,r2=r1+1;
tre[rt].sum=tre[r1].sum+tre[r2].sum;
tre[rt].lmax=Max(tre[r1].lmax,tre[r1].sum+tre[r2].lmax);
tre[rt].lmin=Min(tre[r1].lmin,tre[r1].sum+tre[r2].lmin);
}
void build(int rt,int l,int r)
{
tre[rt].lazy=tre[rt].xr=0;
if (l==r)
{
int tmp;
if (str[r]=='(') tmp=-1;
else tmp=1;
tre[rt].sum=tre[rt].lmax=tre[rt].lmin=tmp;
return ;
}
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
pushup(rt);
}
void Txor(int rt)
{
if (tre[rt].lazy) tre[rt].lazy=-tre[rt].lazy;
else tre[rt].xr^=1;
}
void pushdown(int rt,int k)
{
if (tre[rt].lazy)
{
tre[rt<<1].lazy=tre[rt<<1|1].lazy=tre[rt].lazy;
tre[rt<<1].sum=(k-(k>>1))*tre[rt].lazy;
tre[rt<<1|1].sum=(k>>1)*tre[rt].lazy;
tre[rt<<1].lmax=Max(-1,tre[rt<<1].sum);
tre[rt<<1|1].lmax=Max(-1,tre[rt<<1|1].sum);
tre[rt<<1].lmin=Min(1,tre[rt<<1].sum);
tre[rt<<1|1].lmin=Min(1,tre[rt<<1|1].sum);
tre[rt<<1].xr=tre[rt<<1|1].xr=0;
tre[rt].lazy=0;
}
if (tre[rt].xr)
{
Txor(rt<<1);
Txor(rt<<1|1);
tre[rt<<1].sum=-tre[rt<<1].sum;
tre[rt<<1|1].sum=-tre[rt<<1|1].sum;
int t=tre[rt<<1].lmax;
tre[rt<<1].lmax=-tre[rt<<1].lmin;
tre[rt<<1].lmin=-t;
t=tre[rt<<1|1].lmax;
tre[rt<<1|1].lmax=-tre[rt<<1|1].lmin;
tre[rt<<1|1].lmin=-t;
tre[rt].xr=0;
}
}
void update(int rt,int l,int r,int L,int R,int op)
{
if (L<=l&&r<=R)
{
int t=r-l+1;
if (op<0)
{
tre[rt].lmax=-1;
tre[rt].lmin=-t;
tre[rt].sum=-t;
tre[rt].lazy=-1;
tre[rt].xr=0;
}
else if (op>0)
{
tre[rt].lmax=t;
tre[rt].lmin=1;
tre[rt].sum=t;
tre[rt].lazy=1;
tre[rt].xr=0;
}
else
{
tre[rt].sum=-tre[rt].sum;
t=tre[rt].lmax;
tre[rt].lmax=-tre[rt].lmin;
tre[rt].lmin=-t;
Txor(rt);
}
return ;
}
if (l>=r) return ;
pushdown(rt,r-l+1);
int m=(l+r)>>1;
if (L<=m) update(rt<<1,l,m,L,R,op);
if (R>m) update(rt<<1|1,m+1,r,L,R,op);
pushup(rt);
}
Node query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return tre[rt];
pushdown(rt,r-l+1);
int m=(l+r)>>1,f1=0,f2=0;
Node t,r1,r2;
if (L<=m) { r1=query(rt<<1,l,m,L,R); f1=1; }
if (R>m) { r2=query(rt<<1|1,m+1,r,L,R); f2=1; }
if (f1&&f2)
{
t.sum=r1.sum+r2.sum;
t.lmax=Max(r1.lmax,r1.sum+r2.lmax);
t.lmin=Min(r1.lmin,r1.sum+r2.lmin);
}
else if (f1) t=r1;
else t=r2;
return t;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int ncase,a,b,i,n,q,t,T=0;
char op[55],op2[55];
scanf("%d",&ncase);
while (ncase--)
{
scanf("%d %s",&n,str);
n--; build(1,0,n);
scanf("%d",&q);
printf("Case %d:\n",++T);
while (q--)
{
scanf("%s %d %d",op2,&a,&b);
if (a>b) a^=b,b^=a,a^=b;
switch (op2[0])
{
case 's':
{
scanf("%s",op);
if (op[0]=='(') t=-1;
else t=1;
update(1,0,n,a,b,t);
break;
}
case 'r':
{
update(1,0,n,a,b,0);
break;
}
default :
{
if ((b-a)&1)
{
Node tmp=query(1,0,n,a,b);
if (tmp.sum==0&&tmp.lmax<=0) printf("YES\n");
else printf("NO\n");
// printf("sum=%d lmax=%d lmin=%d\n",tmp.sum,tmp.lmax,tmp.lmin);
}
else printf("NO\n");
}
}
// for (int i=1;i<=13;i++)
// printf("i=%d sum=%d lmax=%d lmin=%d lazy=%d xr=%d\n",i,tre[i].sum,tre[i].lmax,tre[i].lmin,tre[i].lazy,tre[i].xr);
}
puts("");
}
return 0;
}