zoukankan      html  css  js  c++  java
  • hdu 3397 线段树综合

    思路:

           线段树结构更新维护,结构内部包括  1的最大左连续、最大右连续、最大连续长度,0的最大左连续、最大右连续、最大连续长度,1的个数、覆盖值、取反,一共9个值,其中的取反操作要特别注意,其余的看代码吧。。

           如果代码看不懂的话,建议先做一下区间最大连续和、还有poj 3225.

    View Code
      1 #include<iostream>
      2 #include<stdio.h>
      3 using namespace std;
      4 const int N = 100003;
      5 struct node
      6 {
      7        int lo,ro,mo;
      8        int lz,rz,mz;
      9        int oc,cover,re; 
     10        int len;
     11 }tree[N<<2];
     12 int Max(int a,int b)
     13 {
     14     return a>b?a:b;
     15 }
     16 void Get_Re(int t)
     17 {
     18      if(tree[t].cover!=-1)tree[t].cover^=1;
     19      else tree[t].re^=1;
     20 }
     21 void PushDown(int t,int m)
     22 {
     23      if(tree[t].cover!=-1)
     24      {
     25         int t1=t<<1;
     26         int t2=t1|1;
     27         int ll=m-(m>>1),rr=(m>>1);
     28         tree[t1].cover=tree[t2].cover=tree[t].cover;
     29         tree[t1].re=tree[t2].re=0;
     30         tree[t1].lo=tree[t1].ro=tree[t1].mo=(tree[t].cover?ll:0);
     31         tree[t1].lz=tree[t1].rz=tree[t1].mz=(tree[t].cover?0:ll);
     32         tree[t2].lo=tree[t2].ro=tree[t2].mo=(tree[t].cover?rr:0);
     33         tree[t2].lz=tree[t2].rz=tree[t2].mz=(tree[t].cover?0:rr);
     34         tree[t1].oc=(tree[t].cover?ll:0);
     35         tree[t2].oc=(tree[t].cover?rr:0);
     36         tree[t].cover=-1;
     37      }
     38      if(tree[t].re)
     39      {
     40         int t1=t<<1;
     41         int t2=t1|1;
     42         int ll=m-(m>>1),rr=(m>>1);
     43         Get_Re(t1);Get_Re(t2);
     44         swap(tree[t1].lo,tree[t1].lz);swap(tree[t1].ro,tree[t1].rz);swap(tree[t1].mo,tree[t1].mz);
     45         tree[t1].oc=ll-tree[t1].oc;
     46         swap(tree[t2].lo,tree[t2].lz);swap(tree[t2].ro,tree[t2].rz);swap(tree[t2].mo,tree[t2].mz);  
     47         tree[t2].oc=rr-tree[t2].oc;
     48         tree[t].re=0;
     49      }
     50 }
     51 void PushUp(int t,int m)
     52 {
     53      int t1=t<<1;
     54      int t2=t1|1;
     55      int ll=m-(m>>1),rr=m>>1;
     56      tree[t].oc=tree[t1].oc+tree[t2].oc;
     57      
     58      tree[t].lo=tree[t1].lo;
     59      if(tree[t].lo==ll)tree[t].lo+=tree[t2].lo;
     60      tree[t].ro=tree[t2].ro;
     61      if(tree[t].ro==rr)tree[t].ro+=tree[t1].ro;
     62      tree[t].mo=Max(tree[t1].ro+tree[t2].lo,Max(tree[t1].mo,tree[t2].mo));
     63      
     64      tree[t].lz=tree[t1].lz;
     65      if(tree[t].lz==ll)tree[t].lz+=tree[t2].lz;
     66      tree[t].rz=tree[t2].rz;
     67      if(tree[t].rz==rr)tree[t].rz+=tree[t1].rz;
     68      tree[t].mz=Max(tree[t1].rz+tree[t2].lz,Max(tree[t1].mz,tree[t2].mz));
     69 }
     70 void build(int t,int l,int r)
     71 {
     72      tree[t].re=0;
     73      tree[t].cover=-1;
     74      tree[t].len=(r-l+1);
     75      if(l==r)
     76      {
     77         scanf("%d",&tree[t].oc);
     78         tree[t].lo=tree[t].ro=tree[t].mo=(tree[t].oc);
     79         tree[t].lz=tree[t].rz=tree[t].mz=(tree[t].oc?0:1);
     80         return ;
     81      }
     82      int m=(l+r)>>1;
     83      build(t<<1,l,m);
     84      build(t<<1|1,m+1,r);
     85      PushUp(t,r-l+1);
     86 }
     87 void update(int t,int l,int r,int L,int R,int o,int val)
     88 {
     89      if(L<=l&&r<=R)
     90      {
     91         if(o==2)
     92         {
     93            Get_Re(t);
     94            tree[t].oc=(r-l+1)-tree[t].oc;
     95            swap(tree[t].lo,tree[t].lz);swap(tree[t].ro,tree[t].rz);swap(tree[t].mo,tree[t].mz);
     96         }
     97         else
     98         {
     99            tree[t].lo=tree[t].ro=tree[t].mo=(val?r-l+1:0);
    100            tree[t].lz=tree[t].rz=tree[t].mz=(val?0:r-l+1);
    101            tree[t].oc=(val?(r-l+1):0);
    102            tree[t].cover=val;
    103            tree[t].re=0;
    104         }   
    105         return ;           
    106      }
    107      PushDown(t,r-l+1);
    108      int m=(l+r)>>1;
    109      if(L<=m)update(t<<1,l,m,L,R,o,val);
    110      if(R>m)update(t<<1|1,m+1,r,L,R,o,val);
    111      PushUp(t,r-l+1);
    112 }
    113 int query1(int t,int l,int r,int L,int R)
    114 {
    115      if(L<=l&&r<=R)return tree[t].oc;
    116      if(l==r)return 0;
    117      PushDown(t,r-l+1);
    118      int m=(l+r)>>1;
    119      int answer=0;
    120      if(L<=m)answer+=query1(t<<1,l,m,L,R);
    121      if(R>m)answer+=query1(t<<1|1,m+1,r,L,R);
    122      return answer;
    123 }
    124 node query2(int t,int l,int r,int L,int R)
    125 {
    126      node temp={0};
    127      if(L<=l&&r<=R)return tree[t];
    128      if(l==r)return tree[t];
    129      PushDown(t,r-l+1);
    130      int m=(l+r)>>1;
    131      node t1,t2;
    132      int flag1=0,flag2=0;
    133      if(L<=m){t1=query2(t<<1,l,m,L,R);flag1=1;}
    134      if(R>m){t2=query2(t<<1|1,m+1,r,L,R);flag2=1;}
    135      if(flag1&&flag2)
    136      {
    137         temp.len=t1.len+t2.len;
    138         temp.lo=t1.lo;
    139         if(temp.lo==t1.len)temp.lo+=t2.lo;
    140         temp.ro=t2.ro;
    141         if(temp.ro==t2.len)temp.ro+=t1.ro;
    142         temp.mo=Max(t1.ro+t2.lo,Max(t1.mo,t2.mo));
    143         return temp;
    144      }
    145      else
    146        if(flag1)return t1;
    147        else return t2;
    148 }
    149 int main()
    150 {
    151    // freopen("in.txt","r",stdin);
    152   //  freopen("out2.txt","w",stdout);
    153     int Case,n,m,o,a,b;
    154     scanf("%d",&Case);
    155     while(Case--)
    156     {
    157         scanf("%d%d",&n,&m);
    158         n--;
    159         build(1,0,n);
    160         while (m--)
    161         {
    162              scanf("%d%d%d",&o,&a,&b);
    163              if(o<=2)
    164                 update(1,0,n,a,b,o,o);
    165              else
    166              {
    167                 if(o==3)printf("%d\n",query1(1,0,n,a,b));
    168                 else 
    169                 {
    170                    node temp=query2(1,0,n,a,b);
    171                    printf("%d\n",temp.mo);
    172                 }
    173              }
    174         }
    175     }
    176     return 0;    
    177 }
  • 相关阅读:
    1105 Spiral Matrix (25分)(蛇形填数)
    1104 Sum of Number Segments (20分)(long double)
    1026 Table Tennis (30分)(模拟)
    1091 Acute Stroke (30分)(bfs,连通块个数统计)
    1095 Cars on Campus (30分)(排序)
    1098 Insertion or Heap Sort (25分)(堆排序和插入排序)
    堆以及堆排序详解
    1089 Insert or Merge (25分)
    1088 Rational Arithmetic (20分)(模拟)
    1086 Tree Traversals Again (25分)(树的重构与遍历)
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2737664.html
Copyright © 2011-2022 走看看