题目链接:https://www.luogu.com.cn/problem/P2572

Luogu P2572 [SCOI2010] 序列操作(线段树)_#include

 

 

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e5+11,Tree_Sz=5e5+11;
  4 int n,m,a[N];
  5 
  6 inline int re_ad() {
  7     char ch=getchar(); int x=0,f=1;
  8     while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
  9     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 10     return x*f;
 11 }
 12 
 13 struct SegmentTree {
 14     struct Node {
 15         int sum,val[2],lmax[2],rmax[2],tag,rev;
 16     }t[Tree_Sz];
 17     inline void Pushup(int d,int l,int r) {
 18         int mid=(l+r)>>1;
 19         for(int i=0;i<=1;++i) t[d].lmax[i]=t[d<<1].lmax[i]==mid-l+1 ? mid-l+1+t[d<<1|1].lmax[i] : t[d<<1].lmax[i];
 20         for(int i=0;i<=1;++i) t[d].rmax[i]=t[d<<1|1].rmax[i]==r-mid ? r-mid+t[d<<1].rmax[i] : t[d<<1|1].rmax[i];
 21         for(int i=0;i<=1;++i) t[d].val[i]=max(max(t[d<<1].val[i],t[d<<1|1].val[i]),t[d<<1].rmax[i]+t[d<<1|1].lmax[i]);
 22         t[d].sum=t[d<<1].sum+t[d<<1|1].sum;
 23     }
 24     inline void pushdown1(int d,int l,int r) {
 25         int tg=t[d].tag,mid=(l+r)>>1;
 26         t[d<<1].tag=t[d<<1|1].tag=t[d].tag;
 27         t[d<<1].rev=t[d<<1|1].rev=t[d].rev=0;
 28         t[d<<1].sum=tg*(mid-l+1);
 29         t[d<<1].val[tg]=t[d<<1].lmax[tg]=t[d<<1].rmax[tg]=mid-l+1;
 30         t[d<<1].val[tg^1]=t[d<<1].lmax[tg^1]=t[d<<1].rmax[tg^1]=0;
 31         t[d<<1|1].sum=tg*(r-mid);
 32         t[d<<1|1].val[tg]=t[d<<1|1].lmax[tg]=t[d<<1|1].rmax[tg]=r-mid;
 33         t[d<<1|1].val[tg^1]=t[d<<1|1].lmax[tg^1]=t[d<<1|1].rmax[tg^1]=0;
 34         t[d].tag=-1;
 35     }
 36     inline void pushdown2(int d,int l,int r) {
 37         int mid=(l+r)>>1;
 38         if(t[d<<1].tag!=-1) t[d<<1].tag^=1,t[d<<1].rev=0;
 39         else t[d<<1].rev^=1;
 40         t[d<<1].sum=mid-l+1-t[d<<1].sum;
 41         swap(t[d<<1].val[0],t[d<<1].val[1]);
 42         swap(t[d<<1].lmax[0],t[d<<1].lmax[1]);
 43         swap(t[d<<1].rmax[0],t[d<<1].rmax[1]);
 44         if(t[d<<1|1].tag!=-1) t[d<<1|1].tag^=1,t[d<<1|1].rev=0;
 45         else t[d<<1|1].rev^=1;
 46         t[d<<1|1].sum=r-mid-t[d<<1|1].sum;
 47         swap(t[d<<1|1].val[0],t[d<<1|1].val[1]);
 48         swap(t[d<<1|1].lmax[0],t[d<<1|1].lmax[1]);
 49         swap(t[d<<1|1].rmax[0],t[d<<1|1].rmax[1]);
 50         t[d].rev=0;
 51     }
 52     inline void Pushdown(int d,int l,int r) {
 53         if(t[d].tag!=-1) pushdown1(d,l,r);
 54         else if(t[d].rev) pushdown2(d,l,r);
 55     }
 56     void build(int d,int l,int r) {
 57         t[d].tag=-1,t[d].rev=0;
 58         if(l==r) {
 59             int tg=a[l];
 60             t[d].sum=tg;
 61             t[d].val[tg]=t[d].lmax[tg]=t[d].rmax[tg]=1;
 62             t[d].val[tg^1]=t[d].lmax[tg^1]=t[d].rmax[tg^1]=0;
 63             return ;
 64         }
 65         int mid=(l+r)>>1;
 66         build(d<<1,l,mid);
 67         build(d<<1|1,mid+1,r);
 68         Pushup(d,l,r);
 69     }
 70     inline void Build() {
 71         build(1,1,n);
 72     }
 73     inline void update1(int d,int l,int r,int z) {
 74         t[d].tag=z,t[d].rev=0,t[d].sum=z*(r-l+1);
 75         t[d].val[z]=t[d].lmax[z]=t[d].rmax[z]=r-l+1;
 76         t[d].val[z^1]=t[d].lmax[z^1]=t[d].rmax[z^1]=0;
 77     }
 78     inline void update2(int d,int l,int r,int z) {
 79         if(t[d].tag!=-1) t[d].tag^=1,t[d].rev=0;
 80         else t[d].rev^=1;
 81         t[d].sum=r-l+1-t[d].sum;
 82         swap(t[d].val[0],t[d].val[1]);
 83         swap(t[d].lmax[0],t[d].lmax[1]);
 84         swap(t[d].rmax[0],t[d].rmax[1]);
 85     }
 86     inline void Update(int d,int l,int r,int z) {
 87         if(z==2) update2(d,l,r,z);
 88         else update1(d,l,r,z);
 89     }
 90     void modify(int d,int l,int r,int x,int y,int z) {
 91         if(x<=l && r<=y) {
 92             Update(d,l,r,z);
 93             return ;
 94         }
 95         Pushdown(d,l,r);
 96         int mid=(l+r)>>1;
 97         if(x<=mid) modify(d<<1,l,mid,x,y,z);
 98         if(y>=mid+1) modify(d<<1|1,mid+1,r,x,y,z);
 99         Pushup(d,l,r);
100     }
101     inline void Modify(int x,int y,int z) {
102         modify(1,1,n,x,y,z);
103     }
104     int query1(int d,int l,int r,int x,int y) {
105         if(x<=l && r<=y) return t[d].sum;
106         Pushdown(d,l,r);
107         int mid=(l+r)>>1,res=0;
108         if(x<=mid) res+=query1(d<<1,l,mid,x,y);
109         if(y>=mid+1) res+=query1(d<<1|1,mid+1,r,x,y);
110         return res;
111     }
112     int query2(int d,int l,int r,int x,int y) {
113         if(x<=l && r<=y) return t[d].val[1];
114         Pushdown(d,l,r);
115         int mid=(l+r)>>1,res=0;
116         if(x<=mid) res=max(res,query2(d<<1,l,mid,x,y));
117         if(y>=mid+1) res=max(res,query2(d<<1|1,mid+1,r,x,y));
118         if(x<=mid && y>=mid+1) {
119             int lmin=min(mid-x+1,t[d<<1].rmax[1]);
120             int rmin=min(y-mid,t[d<<1|1].lmax[1]);
121             res=max(res,lmin+rmin);
122         }
123         return res;
124     }
125     inline void Query(int x,int y,int z) {
126         if(!z) printf("%d\n",query1(1,1,n,x,y));
127         else printf("%d\n",query2(1,1,n,x,y));
128     }
129     inline void print_search(int d,int l,int r) {
130         cout<<setw(3)<<d<<setw(3)<<l<<setw(3)<<r<<setw(3)<<t[d].sum<<setw(3)<<t[d].tag<<setw(3)<<t[d].rev;
131         cout<<setw(3)<<t[d].val[0]<<setw(3)<<t[d].val[1];
132         cout<<setw(3)<<t[d].lmax[0]<<setw(3)<<t[d].lmax[1];
133         cout<<setw(3)<<t[d].rmax[0]<<setw(3)<<t[d].rmax[1];
134         puts("");
135         if(l==r) return ;
136         int mid=(l+r)>>1;
137         print_search(d<<1,l,mid);
138         print_search(d<<1|1,mid+1,r);
139     }
140 }st;
141 
142 int main()
143 {
144 //    freopen("test.out","w",stdout);
145     n=re_ad(),m=re_ad();
146     for(int i=1;i<=n;++i) a[i]=re_ad();
147     st.Build();
148 //    st.print_search(1,1,n); puts("");
149     for(int i=1,op,x,y;i<=m;++i) {
150         op=re_ad(),x=re_ad(),y=re_ad();
151         if(op<=2) st.Modify(x+1,y+1,op);
152         else st.Query(x+1,y+1,op-3);
153 //        st.print_search(1,1,n); puts("");
154     }
155     return 0;
156 }