BZOJ 1858 线段树

Posted on 2016-09-28 19:09  yyjxx2010xyu  阅读(151)  评论(0编辑  收藏  举报

标记会重叠需要判断.

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 inline int Max(int x,int y) {return x>y?x:y;}
  4 inline int Max3(int x,int y,int z) {return Max(x,Max(y,z));}
  5 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;}
  6 //===========================================
  7 const int Maxn=200100;
  8 struct Node
  9 {
 10     int Len,Size0,Size1,l0,l1,r0,r1,Max0,Max1,Tag,Rev;
 11 }Tree[Maxn<<2];
 12 int n,m,l,r,Type,a[Maxn];
 13 inline void Push_Up(int o)
 14 {
 15     Tree[o].Len=Tree[o<<1].Len+Tree[o<<1|1].Len;
 16     Tree[o].Size0=Tree[o<<1].Size0+Tree[o<<1|1].Size0;
 17     Tree[o].Size1=Tree[o<<1].Size1+Tree[o<<1|1].Size1;
 18     Tree[o].l0=(Tree[o<<1].Len!=Tree[o<<1].l0)?Tree[o<<1].l0:Tree[o<<1].Len+Tree[o<<1|1].l0;
 19     Tree[o].r0=(Tree[o<<1|1].Len!=Tree[o<<1|1].r0)?Tree[o<<1|1].r0:Tree[o<<1|1].Len+Tree[o<<1].r0;
 20     Tree[o].l1=(Tree[o<<1].Len!=Tree[o<<1].l1)?Tree[o<<1].l1:Tree[o<<1].Len+Tree[o<<1|1].l1;
 21     Tree[o].r1=(Tree[o<<1|1].Len!=Tree[o<<1|1].r1)?Tree[o<<1|1].r1:Tree[o<<1|1].Len+Tree[o<<1].r1;
 22     Tree[o].Max0=Max3(Tree[o<<1].r0+Tree[o<<1|1].l0,Tree[o<<1].Max0,Tree[o<<1|1].Max0);
 23     Tree[o].Max1=Max3(Tree[o<<1].r1+Tree[o<<1|1].l1,Tree[o<<1].Max1,Tree[o<<1|1].Max1);
 24 }
 25 inline void Swap_Tree(int o)
 26 {
 27     Swap(Tree[o].l1,Tree[o].l0),Swap(Tree[o].r0,Tree[o].r1),Swap(Tree[o].Max0,Tree[o].Max1),Swap(Tree[o].Size0,Tree[o].Size1);
 28 }
 29 inline void Update(int o,int v)
 30 {
 31     if (v==1) Tree[o].Size0=Tree[o].l0=Tree[o].r0=Tree[o].Max0=Tree[o].Len,Tree[o].Size1=Tree[o].l1=Tree[o].r1=Tree[o].Max1=0;
 32     if (v==2) Tree[o].Size0=Tree[o].l0=Tree[o].r0=Tree[o].Max0=0,Tree[o].Size1=Tree[o].l1=Tree[o].r1=Tree[o].Max1=Tree[o].Len;
 33 }
 34 inline void Push_Down(int o)
 35 {
 36     if (Tree[o].Rev)
 37     {
 38         if (Tree[o<<1].Tag) Tree[o<<1].Tag=(Tree[o<<1].Tag==1)?2:1,Swap_Tree(o<<1); else Tree[o<<1].Rev^=1,Swap_Tree(o<<1);
 39         if (Tree[o<<1|1].Tag) Tree[o<<1|1].Tag=(Tree[o<<1|1].Tag==1)?2:1,Swap_Tree(o<<1|1); else Tree[o<<1|1].Rev^=1,Swap_Tree(o<<1|1);
 40         Tree[o].Rev=0;
 41     }
 42     if (Tree[o].Tag)
 43     {
 44         Update(o<<1,Tree[o].Tag),Update(o<<1|1,Tree[o].Tag);
 45         Tree[o<<1].Tag=Tree[o<<1|1].Tag=Tree[o].Tag;
 46         Tree[o].Tag=0;
 47     }
 48      
 49 }
 50 void Build(int o,int l,int r)
 51 {
 52     if (l==r) 
 53     {
 54         Tree[o].Len=1;
 55         if (a[l]==0) Tree[o].l0=Tree[o].r0=Tree[o].Max0=Tree[o].Size0=1;
 56         if (a[l]==1) Tree[o].l1=Tree[o].r1=Tree[o].Max1=Tree[o].Size1=1;
 57         return;
 58     }
 59     int mid=(l+r)>>1;
 60     Build(o<<1,l,mid),Build(o<<1|1,mid+1,r);
 61     Push_Up(o);
 62 }
 63 void Modify(int o,int l,int r,int p,int q,int v)
 64 {
 65     if (l==p && r==q)
 66     {
 67         if (Tree[o].Rev) Tree[o].Rev=0;
 68         Update(o,v); Tree[o].Tag=v;
 69         return;
 70     }
 71     int mid=(l+r)>>1;
 72     Push_Down(o);
 73     if (q<=mid) Modify(o<<1,l,mid,p,q,v);
 74     if (p>=mid+1) Modify(o<<1|1,mid+1,r,p,q,v);
 75     if (p<=mid && q>=mid+1) Modify(o<<1,l,mid,p,mid,v),Modify(o<<1|1,mid+1,r,mid+1,q,v);
 76     Push_Up(o);
 77 }
 78 void Revese(int o,int l,int r,int p,int q)
 79 {
 80     Push_Down(o);
 81     if (l==p && r==q)
 82     {
 83         if (Tree[o].Tag) {Tree[o].Tag=(Tree[o].Tag==1)?2:1; Swap_Tree(o); return;} 
 84         Tree[o].Rev^=1;
 85         Swap_Tree(o);
 86         return;
 87     }
 88     int mid=(l+r)>>1;
 89     if (q<=mid) Revese(o<<1,l,mid,p,q);
 90     if (p>=mid+1) Revese(o<<1|1,mid+1,r,p,q);
 91     if (p<=mid && q>=mid+1) Revese(o<<1,l,mid,p,mid),Revese(o<<1|1,mid+1,r,mid+1,q);
 92     Push_Up(o);
 93 }
 94 int Query_Size(int o,int l,int r,int p,int q)
 95 {
 96     Push_Down(o);
 97     if (l==p && r==q) return Tree[o].Size1;
 98     int mid=(l+r)>>1;
 99     if (q<=mid) return Query_Size(o<<1,l,mid,p,q);
100     if (p>=mid+1) return Query_Size(o<<1|1,mid+1,r,p,q);
101     return Query_Size(o<<1,l,mid,p,mid)+Query_Size(o<<1|1,mid+1,r,mid+1,q);
102 }
103 Node Query_Len(int o,int l,int r,int p,int q)
104 {
105     Push_Down(o);
106     if (l==p && r==q) return Tree[o];
107     int mid=(l+r)>>1;
108     if (q<=mid) return Query_Len(o<<1,l,mid,p,q);
109     if (p>=mid+1) return Query_Len(o<<1|1,mid+1,r,p,q);
110     Node L=Query_Len(o<<1,l,mid,p,mid);
111     Node R=Query_Len(o<<1|1,mid+1,r,mid+1,q);
112     Node M;
113     M.Len=L.Len+R.Len;
114     M.l1=(L.Len!=L.l1)?L.l1:L.Len+R.l1;
115     M.r1=(R.Len!=R.r1)?R.r1:R.Len+L.r1;
116     M.Max1=Max3(L.r1+R.l1,L.Max1,R.Max1);
117     return M;
118 }
119 int main()
120 {
121     // freopen("c.in","r",stdin);
122     scanf("%d%d",&n,&m);
123     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
124     Build(1,1,n);
125     for (int i=1;i<=m;i++) 
126     {
127         scanf("%d%d%d",&Type,&l,&r); l++,r++;
128         if (Type==0) Modify(1,1,n,l,r,1);
129         if (Type==1) Modify(1,1,n,l,r,2);
130         if (Type==2) Revese(1,1,n,l,r);
131         if (Type==3) printf("%d\n",Query_Size(1,1,n,l,r));
132         if (Type==4) printf("%d\n",Query_Len(1,1,n,l,r).Max1);
133     }
134     return 0;
135 }
C++