1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#include <iostream> #include <cstdio>
#define endl '\n' #define R Read()
typedef const int &iint;
const int nmax = 100005; const int tmax = 262150; #define ls (x<<1) #define rs (ls|1) #define LL ls,l,mid #define RR rs,mid+1,r using namespace std;
int n,m; bool a[nmax]; int ll,rr; bool qcnt; struct Data { int cnt,lsm,rsm,mx[2]; bool ld,rd; int len; inline void init(const bool &val) { mx[val]=len=lsm=rsm=1; cnt=ld=rd=val; } inline void set(const bool &val) { lsm=rsm=len; cnt=len*val; mx[val]=len,mx[!val]=0; ld=rd=val; } inline void reverse() { ld=!ld,rd=!rd,cnt=len-cnt; swap(mx[0],mx[1]); } inline void merge(const Data &a, const Data &b) { len=a.len+b.len; cnt=a.cnt+b.cnt; ld=a.ld,rd=b.rd; lsm=a.lsm; if (a.lsm==a.len&&a.ld==b.ld) lsm+=b.lsm; rsm=b.rsm; if (b.rsm==b.len&&b.rd==a.rd) rsm+=a.rsm; mx[0]=mx[1]=0; mx[a.rd]+=a.rsm; mx[b.ld]+=b.lsm; mx[0]=max(mx[0],max(a.mx[0],b.mx[0])); mx[1]=max(mx[1],max(a.mx[1],b.mx[1])); } } d[tmax]; struct Tag { bool set,sval; bool rev; inline operator bool() const { return set||rev; } inline void operator+=(const Tag &t) { if (t.set) { set=1; sval=t.sval; rev=0; } else if (t.rev) { if (set) sval=!sval; else rev^=1; } } inline void apply(Data &d) const { if (set) d.set(sval); else if (rev) d.reverse(); } inline void clear() { set=sval=rev=0; } } tag[tmax],tt; inline void pu(iint x) { d[x].merge(d[ls],d[rs]); } inline void pd(iint x) { Tag &t=tag[x]; if (!t) return; t.apply(d[ls]),tag[ls]+=t; t.apply(d[rs]),tag[rs]+=t; t.clear(); } void build(iint x=1, iint l=1, iint r=n) { if (l==r) { d[x].init(a[l]); return; } int mid=(l+r)>>1; build(LL); build(RR); pu(x); } void update(iint x=1, iint l=1, iint r=n) { if (ll<=l&&r<=rr) { tag[x]+=tt; tt.apply(d[x]); return; } int mid=(l+r)>>1; pd(x); if (mid>=ll) update(LL); if (mid<rr) update(RR); pu(x); } Data query(iint x=1, iint l=1, iint r=n) { if (ll<=l&&r<=rr) return d[x]; int mid=(l+r)>>1; pd(x); if (mid<ll) return query(RR); if (mid>=rr) return query(LL); Data ret; ret.merge(query(LL),query(RR)); return ret; } int main() { int i; n=R,m=R; for (i=1;i<=n;i++) a[i]=R; build(); while (m--) { i=R,ll=R+1,rr=R+1; switch (i) { case 0:tt={1,0,0};update();break; case 1:tt={1,1,0};update();break; case 2:tt={0,0,1};update();break; case 3:cout<<query().cnt<<endl;break; case 4:cout<<query().mx[1]<<endl;break; } } return 0; }
|