UESTC 1546 线段树 区间合并

相当郁闷啊,初看,题目描述简单,感觉很容易,直接由区间'('数判断,敲出来之后“意外”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;   
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值