bzoj1858: [Scoi2010]序列操作
很早之前就做了
线段树裸题
据说可以只维护一段区间是否全是1或者0,复杂度应该没有保证?也不觉得更好写一些。。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a+".in").c_str(), "r", stdin); 12 freopen((a+".out").c_str(), "w", stdout); 13 } 14 15 struct Data { 16 int s[2], l[2], r[2], m[2]; 17 Data() { 18 memset(s, 4*(sizeof s), 0); 19 } 20 }; 21 22 int n; 23 24 Data merge(const Data& lhs, const Data& rhs) { 25 Data res; 26 27 int n1 = lhs.s[0] + lhs.s[1]; 28 int n2 = rhs.s[0] + rhs.s[1]; 29 30 for(int i = 0; i < 2; i++) { 31 res.s[i] = lhs.s[i] + rhs.s[i]; 32 res.l[i] = lhs.l[i]; 33 if(lhs.l[i] == n1) res.l[i] += rhs.l[i]; 34 res.r[i] = rhs.r[i]; 35 if(rhs.r[i] == n2) res.r[i] += lhs.r[i]; 36 res.m[i] = max(max(lhs.m[i], rhs.m[i]), lhs.r[i] + rhs.l[i]); 37 } 38 39 return res; 40 } 41 42 const int N = 100000 + 10; 43 44 int a[N]; 45 46 47 struct SegmentTree { 48 Data da[N * 4]; 49 int tag[N * 4];// -1 : none 2 : rever 50 int lft, rgt, w; 51 52 void add_tag(int s, int l, int r, int w) { 53 if(w == -1) return; 54 int len = r - l + 1; 55 if(w != 2) { 56 tag[s] = w; 57 da[s].s[w] = da[s].m[w] = da[s].l[w] = da[s].r[w] = len; 58 w ^= 1; 59 da[s].s[w] = da[s].m[w] = da[s].l[w] = da[s].r[w] = 0; 60 }else { 61 swap(da[s].s[0], da[s].s[1]); 62 swap(da[s].l[0], da[s].l[1]); 63 swap(da[s].r[0], da[s].r[1]); 64 swap(da[s].m[0], da[s].m[1]); 65 if(tag[s] == -1) tag[s] = w; 66 else if(tag[s] == 2) tag[s] = -1; 67 else tag[s] ^= 1; 68 } 69 } 70 71 #define mid ((l + r) >> 1) 72 #define ls s << 1, l, mid 73 #define rs s << 1 | 1, mid + 1, r 74 75 void down(int s, int l, int r) { 76 if(tag[s] == -1) return; 77 add_tag(ls, tag[s]); 78 add_tag(rs, tag[s]); 79 tag[s] = -1; 80 } 81 82 void build(int s, int l, int r) { 83 tag[s] = -1; 84 if(l == r) { 85 scanf("%d", &w); 86 da[s].s[w] = da[s].l[w] = da[s].r[w] = da[s].m[w] = 1; 87 w ^= 1; 88 da[s].s[w] = da[s].l[w] = da[s].r[w] = da[s].m[w] = 0; 89 return; 90 } 91 build(ls); 92 build(rs); 93 da[s] = merge(da[s << 1], da[s << 1 | 1]); 94 } 95 96 Data query(int s, int l, int r) { 97 if(lft <= l && r <= rgt) return da[s]; 98 down(s, l, r); 99 if(rgt <= mid) return query(ls); 100 if(mid < lft) return query(rs); 101 return merge(query(ls), query(rs)); 102 } 103 104 void modify(int s, int l, int r) { 105 if(lft <= l && r <= rgt) { 106 add_tag(s, l, r, w); 107 return; 108 } 109 down(s, l, r); 110 if(lft <= mid) modify(ls); 111 if(mid < rgt) modify(rs); 112 da[s] = merge(da[s << 1], da[s << 1 | 1]); 113 } 114 115 #undef mid 116 #undef ls 117 #undef rs 118 119 Data Query(int l, int r) { 120 lft = l, rgt = r; 121 return query(1, 1, n); 122 } 123 124 void Modify(int l, int r, int w) { 125 lft = l, rgt = r, this->w = w; 126 modify(1, 1, n); 127 } 128 129 }seg; 130 131 int main() { 132 int m, opt, l, r; 133 scanf("%d%d", &n, &m); 134 seg.build(1, 1, n); 135 // cerr << seg.Query(1, 6).s[1] << endl; 136 while(m--) { 137 scanf("%d%d%d", &opt, &l, &r); ++l, ++r; 138 if(opt <= 2) seg.Modify(l, r, opt); 139 else if(opt == 3) printf("%d\n", seg.Query(l, r).s[1]); 140 else printf("%d\n", seg.Query(l, r).m[1]); 141 } 142 143 return 0; 144 }
原文出处http://www.cnblogs.com/showson/