题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 这道题是一个我认为非常非常麻烦的题,操作非常多,而且要打两个懒惰标记,并且懒惰标记有优先级之分,当一个节点收到一个覆盖标记的时候,取反标记就应该立即消失,这是一个麻烦,另外一个麻烦就是一个结点需要维持七个变量以满足本题的操作和所求。区间合并 的基本思想不用赘述,下面有一个成形的代码(貌似有bug),不过想法已经体现出来。
view code 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define lson l, m, rt<<1 6 #define rson m + 1, r, rt<<1|1 7 const int maxn = 111111; 8 int l1s[maxn<<2], r1s[maxn<<2], m1s[maxn<<2], l0s[maxn<<2], r0s[maxn<<2], m0s[maxn<<2], sum[maxn<<2]; 9 int cover[maxn<<2], col[maxn<<2]; 10 void PushDown(int rt, int m){ 11 if (cover[rt] != -1){ 12 cover[rt<<1] = cover[rt<<1|1] = cover[rt]; 13 col[rt] = col[rt<<1] = col[rt<<1|1] = 0; 14 l1s[rt<<1] = r1s[rt<<1] = m1s[rt<<1] = sum[rt<<1] = cover[rt] ? m - (m >> 1) : 0; 15 l1s[rt<<1|1] = r1s[rt<<1|1] = m1s[rt<<1|1] = sum[rt<<1|1] = cover[rt] ? (m >> 1) : 0; 16 l0s[rt<<1] = r0s[rt<<1] = m0s[rt<<1] = cover[rt] ? 0 : m - (m >> 1); 17 l0s[rt<<1|1] = r0s[rt<<1|1] = m0s[rt<<1|1] = cover[rt] ? 0 : (m >> 1); 18 cover[rt] = -1; 19 } 20 else if (col[rt]){ 21 col[rt<<1] += col[rt]; 22 col[rt<<1|1] += col[rt]; 23 col[rt] %= 2; 24 if (col[rt]){ 25 swap(l1s[rt<<1], l0s[rt<<1]); 26 swap(l1s[rt<<1|1], l0s[rt<<1|1]); 27 swap(r1s[rt<<1], r0s[rt<<1]); 28 swap(r1s[rt<<1|1], r0s[rt<<1|1]); 29 swap(m1s[rt<<1], m0s[rt<<1]); 30 swap(m1s[rt<<1|1], m0s[rt<<1|1]); 31 sum[rt<<1] = (m - (m>>1)) - sum[rt<<1]; 32 sum[rt<<1|1] = (m>>1) - sum[rt>>1|1]; 33 } 34 col[rt] = 0; 35 } 36 } 37 void PushUp(int rt, int m){ 38 l1s[rt] = l1s[rt<<1]; l0s[rt] = l0s[rt<<1]; 39 r1s[rt] = r1s[rt<<1|1]; r0s[rt] = r0s[rt<<1|1]; 40 if (l1s[rt] == m - (m >> 1)) l1s[rt] += l1s[rt<<1|1]; 41 if (r1s[rt] == (m >> 1)) r1s[rt] += r1s[rt<<1]; 42 if (l0s[rt] == m - (m >> 1)) l0s[rt] += l0s[rt<<1|1]; 43 if (r0s[rt] == (m >> 1)) r0s[rt] += r0s[rt<<1]; 44 m1s[rt] = max(l1s[rt<<1|1] + r1s[rt<<1], max(m1s[rt<<1], m1s[rt<<1|1])); 45 m0s[rt] = max(l0s[rt<<1|1] + r0s[rt<<1], max(m0s[rt<<1], m0s[rt<<1|1])); 46 sum[rt] = sum[rt<<1] + sum[rt<<1|1]; 47 } 48 void build(int l, int r, int rt){ 49 cover[rt] = -1; col[rt] = 0; 50 if (l == r){ 51 scanf("%d", &sum[rt]); 52 l1s[rt] = r1s[rt] = m1s[rt] = cover[rt] = sum[rt]; 53 l0s[rt] = r0s[rt] = m0s[rt] = 1 - sum[rt]; 54 return; 55 } 56 int m = (l + r) >> 1; 57 build(lson); 58 build(rson); 59 PushUp(rt, r - l + 1); 60 } 61 void update(int ll, int rr, int c, int l, int r, int rt){ 62 if (ll <= l && rr >= r){ 63 if (c == 2){ 64 col[rt] += 1; 65 sum[rt] = (r - l + 1) - sum[rt]; 66 swap(m1s[rt], m0s[rt]); 67 swap(l1s[rt], l0s[rt]); 68 swap(r1s[rt], r0s[rt]); 69 } 70 else{ 71 l1s[rt] = r1s[rt] = m1s[rt] = sum[rt] = c ? (r - l + 1) : 0; 72 l0s[rt] = r0s[rt] = m0s[rt] = c ? 0 : r - l + 1; 73 col[rt] = 0; 74 cover[rt] = c; 75 } 76 } 77 PushDown(rt, r - l + 1); 78 int m = (l + r) >> 1; 79 if (ll <= m) update(ll, rr, c, lson); 80 if (rr > m) update(ll, rr, c, rson); 81 PushUp(rt, r - l + 1); 82 } 83 int query_sum(int ll, int rr, int l, int r, int rt){ 84 if (ll <= l && rr >= r) return sum[rt]; 85 PushDown(rt, r - l + 1); 86 int m = (l + r) >> 1; 87 int ret = 0; 88 if (ll <= m) ret += query_sum(ll, rr, lson); 89 if (rr > m) ret += query_sum(ll, rr, rson); 90 return ret; 91 } 92 int query_maxlen(int ll, int rr, int l, int r, int rt){ 93 if (ll == l && rr == r) return m1s[rt]; 94 PushDown(rt, r - l + 1); 95 int m = (l + 1) >> 1; 96 if (rr <= m) return query_maxlen(ll, rr, lson); 97 else if (ll >= m) return query_maxlen(ll, rr, rson); 98 else{ 99 int a = query_maxlen(ll, m, lson); 100 int b = query_maxlen(m+1, rr, rson); 101 int c = 0; 102 c += max(r1s[rt<<1], m - ll + 1); 103 c += max(l1s[rt<<1|1], rr - m); 104 return max(a, max(b, c)); 105 } 106 } 107 int main(){ 108 int t; 109 scanf("%d", &t); 110 while(t--){ 111 int op, a, b; 112 int n, m; 113 scanf("%d%d", &n, &m); 114 build(1, n, 1); 115 while(m--){ 116 scanf("%d%d%d", &op, &a, &b); 117 a += 1; b += 1; 118 if (op <= 2) 119 update(a, b, op, 1, n, 1); 120 else if (op == 3){ 121 int ans = query_sum(a, b, 1, n, 1); 122 printf("%d\n", ans); 123 } 124 else{ 125 int ans = query_maxlen(a, b, 1, n, 1); 126 printf("%d\n", ans); 127 } 128 } 129 } 130 return 0; 131
|