hdu Sequence operation

#include<stdio.h>
#define MAXN 100000
struct node{
   int sum;
   int lmax1,rmax1,tmax1;
   int lmax0,rmax0,tmax0;
   int cnt;
   int color;
}tree[MAXN*4];
int Total,Interval_max;
int max(int a,int b)
{  return a>b?a:b;}
void update_info(int l,int r,int mid,int idx)
{
    tree[idx].sum=tree[idx*2].sum+tree[idx*2+1].sum;
    tree[idx].lmax1=tree[idx*2].lmax1;
    if(tree[idx*2].lmax1==(mid-l+1)) tree[idx].lmax1+=tree[idx*2+1].lmax1;
    tree[idx].rmax1=tree[idx*2+1].rmax1;
    if(tree[idx*2+1].rmax1==(r-mid)) tree[idx].rmax1+=tree[idx*2].rmax1;
    tree[idx].tmax1=max(tree[idx*2].tmax1,tree[idx*2+1].tmax1);
    tree[idx].tmax1=max(tree[idx].tmax1,tree[idx*2].rmax1+tree[idx*2+1].lmax1);
    tree[idx].lmax0=tree[idx*2].lmax0;
    if(tree[idx*2].lmax0==(mid-l+1)) tree[idx].lmax0+=tree[idx*2+1].lmax0;
    tree[idx].rmax0=tree[idx*2+1].rmax0;
    if(tree[idx*2+1].rmax0==(r-mid)) tree[idx].rmax0+=tree[idx*2].rmax0;
    tree[idx].tmax0=max(tree[idx*2].tmax0,tree[idx*2+1].tmax0);
    tree[idx].tmax0=max(tree[idx].tmax0,tree[idx*2].rmax0+tree[idx*2+1].lmax0);
}
void build(int l,int r,int idx)
{
    tree[idx].color=0;
    if(l==r)
    {
       scanf("%idx",&tree[idx].tmax1);
       tree[idx].lmax1=tree[idx].rmax1=tree[idx].tmax1;
       tree[idx].cnt=tree[idx].tmax1;
       tree[idx].sum=tree[idx].tmax1;
       tree[idx].lmax0=tree[idx].rmax0=tree[idx].tmax0=1-tree[idx].tmax1;
       return ;
    }
    int m;
    tree[idx].cnt=-1;
    m=(l+r)/2;
    build(l,m,idx*2);
    build(m+1,r,idx*2+1);
    update_info(l,r,m,idx);
}
void push_down(int l,int r,int m,int idx)
{
    if(tree[idx].cnt>=0)
    {
        tree[idx].cnt^=tree[idx].color;
        tree[idx*2].cnt=tree[idx*2+1].cnt=tree[idx].cnt;
        tree[idx*2].color=0;tree[idx*2+1].color=0;
        tree[idx*2].sum=tree[idx*2].lmax1=tree[idx*2].rmax1=tree[idx*2].tmax1=tree[idx].cnt*(m-l+1);
        tree[idx*2].lmax0=tree[idx*2].rmax0=tree[idx*2].tmax0=(1-tree[idx].cnt)*(m-l+1);
        tree[idx*2+1].sum=tree[idx*2+1].lmax1=tree[idx*2+1].rmax1=tree[idx*2+1].tmax1=tree[idx].cnt*(r-m);
        tree[idx*2+1].lmax0=tree[idx*2+1].rmax0=tree[idx*2+1].tmax0=(1-tree[idx].cnt)*(r-m);
        tree[idx].color=0;
        tree[idx].cnt=-1;
        return ;
    }
    if(tree[idx].color==1)
    {
        int t;
        tree[idx*2].sum=m-l+1-tree[idx*2].sum;
        t=tree[idx*2].rmax1;tree[idx*2].rmax1=tree[idx*2].rmax0;tree[idx*2].rmax0=t;
        t=tree[idx*2].lmax1;tree[idx*2].lmax1=tree[idx*2].lmax0;tree[idx*2].lmax0=t;
        t=tree[idx*2].tmax1;tree[idx*2].tmax1=tree[idx*2].tmax0;tree[idx*2].tmax0=t;
        tree[idx*2+1].sum=r-m-tree[idx*2+1].sum;
        t=tree[idx*2+1].rmax1;tree[idx*2+1].rmax1=tree[idx*2+1].rmax0;tree[idx*2+1].rmax0=t;
        t=tree[idx*2+1].lmax1;tree[idx*2+1].lmax1=tree[idx*2+1].lmax0;tree[idx*2+1].lmax0=t;
        t=tree[idx*2+1].tmax1;tree[idx*2+1].tmax1=tree[idx*2+1].tmax0;tree[idx*2+1].tmax0=t;
        tree[idx*2].color^=1;
        tree[idx*2+1].color^=1;
        tree[idx].color=0;
    }
}
void update(int a,int b,int cnt,int l,int r,int idx)
{
    if(a<=l&&r<=b)
    {
      tree[idx].cnt=cnt;
      tree[idx].color=0;
      tree[idx].sum=tree[idx].lmax1=tree[idx].rmax1=tree[idx].tmax1=cnt*(r-l+1);
      tree[idx].rmax0=tree[idx].lmax0=tree[idx].tmax0=(1-cnt)*(r-l+1);
      return;
    }
    int mid=(l+r)/2;
    push_down(l,r,mid,idx);
    if(a<=mid) update(a,b,cnt,l,mid,idx*2);
    if(b>mid)  update(a,b,cnt,mid+1,r,idx*2+1);
    update_info(l,r,mid,idx);
}
void update_xor(int a,int b,int l,int r,int idx)
{
    if(a<=l&&r<=b)
    {
       int t;
       tree[idx].color^=1;
       tree[idx].sum=r-l+1-tree[idx].sum;
       t=tree[idx].rmax1;tree[idx].rmax1=tree[idx].rmax0;tree[idx].rmax0=t;
       t=tree[idx].lmax1;tree[idx].lmax1=tree[idx].lmax0;tree[idx].lmax0=t;
       t=tree[idx].tmax1;tree[idx].tmax1=tree[idx].tmax0;tree[idx].tmax0=t;
      return;
    }
    int m=(l+r)/2;
    push_down(l,r,m,idx);
    if(a<=m) update_xor(a,b,l,m,idx*2);
    if(b>m)  update_xor(a,b,m+1,r,idx*2+1);
    update_info(l,r,m,idx);
}
void Query_sum(int a,int b,int l,int r,int idx)
{
    if(a<=l&&r<=b)
    {
       Total+=tree[idx].sum;
      return;
    }
    int mid=(l+r)/2;
    push_down(l,r,mid,idx);
    if(a<=mid) Query_sum(a,b,l,mid,idx*2);
    if(b>mid)  Query_sum(a,b,mid+1,r,idx*2+1);
    update_info(l,r,mid,idx);
}
void Query_Interval(int a,int b,int l,int r,int idx)
{
    if(a<=l&&r<=b)
    {
       if(Interval_max<tree[idx].tmax1) Interval_max=tree[idx].tmax1;
      return;
    }
    int mid=(l+r)/2;
    push_down(l,r,mid,idx);
    if(a<=mid&&mid<b)
    {
     int s=0;
     if((mid-a+1)>tree[idx*2].rmax1) s+=tree[idx*2].rmax1;
     else
        s+=mid-a+1;
     if((b-mid)>tree[idx*2+1].lmax1) s+=tree[idx*2+1].lmax1;
     else
        s+=b-mid;
      if(s>Interval_max) Interval_max=s;
    }
    if(a<=mid&&Interval_max<tree[idx*2].tmax1)   Query_Interval(a,b,l,mid,idx*2);
    if(b>mid&&Interval_max<tree[idx*2+1].tmax1)  Query_Interval(a,b,mid+1,r,idx*2+1);
    update_info(l,r,mid,idx);
}
int main()
{
   int n,m,t;
   int a,b,op;
   scanf("%idx",&t);
   while(t--)
   {
      scanf("%d %d",&n,&m);
      n--;
      build(0,n,1);
      while(m--)
      {
         scanf("%d %d %d",&op,&a,&b);
         if(op==0||op==1)
         {
            update(a,b,op,0,n,1);
         }
         if(op==2)
         {
            update_xor(a,b,0,n,1);
         }
         if(op==3)
         {
            Total=0;
            Query_sum(a,b,0,n,1);
            printf("%d\n",Total);
         }
         if(op==4)
         {
            Interval_max=0;
            Query_Interval(a,b,0,n,1);
            printf("%d\n",Interval_max);
         }
      }
   }
   return 0;
}

 

posted @ 2012-07-17 21:28  zhuiy  阅读(137)  评论(0编辑  收藏  举报