hdu 3397 Sequence operation 线段树
给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数。
需要将数组开成二维的, 然后区间0, 1翻转只需要交换一个数组的第二维就可以。
一个数组记录区间最长, 一个记录前缀, 一个记录后缀, 一个记录总数, 一个lazy标记, 一个xor标记。
如果遇到覆盖的情况, 那么这个区间如果原先有xor标记, 那么直接将xor清零。
这个题我写的代码可能不太适合人类观看............
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 const int maxn = 1e5+5; 20 int maxx[maxn<<2][2], pre_max[maxn<<2][2], suf_max[maxn<<2][2], XOR[maxn<<2], lazy[maxn<<2], sum[maxn<<2][2]; 21 void pushUp(int rt, int sign, int m) { 22 maxx[rt][sign] = max(maxx[rt<<1][sign], maxx[rt<<1|1][sign]); 23 pre_max[rt][sign] = pre_max[rt<<1][sign]; 24 suf_max[rt][sign] = suf_max[rt<<1|1][sign]; 25 sum[rt][sign] = sum[rt<<1][sign]+sum[rt<<1|1][sign]; 26 if(pre_max[rt][sign] == (m-(m>>1))) 27 pre_max[rt][sign] += pre_max[rt<<1|1][sign]; 28 if(suf_max[rt][sign] == (m>>1)) 29 suf_max[rt][sign] += suf_max[rt<<1][sign]; 30 maxx[rt][sign] = max(maxx[rt][sign], suf_max[rt<<1][sign]+pre_max[rt<<1|1][sign]); 31 } 32 void change(int rt) { 33 swap(sum[rt][0], sum[rt][1]); 34 swap(maxx[rt][0], maxx[rt][1]); 35 swap(pre_max[rt][0], pre_max[rt][1]); 36 swap(suf_max[rt][0], suf_max[rt][1]); 37 XOR[rt]^=1; 38 } 39 void pushDown(int rt, int m) { 40 if(~lazy[rt]) { 41 XOR[rt<<1] = XOR[rt<<1|1] = 0; 42 int sign = lazy[rt]; 43 maxx[rt<<1][sign] = sum[rt<<1][sign] = pre_max[rt<<1][sign] = suf_max[rt<<1][sign] = (m-(m>>1)); 44 maxx[rt<<1|1][sign] = sum[rt<<1|1][sign] = pre_max[rt<<1|1][sign] = suf_max[rt<<1|1][sign] = (m>>1); 45 sign^=1; 46 maxx[rt<<1][sign] = sum[rt<<1][sign] = pre_max[rt<<1][sign] = suf_max[rt<<1][sign] = 0; 47 maxx[rt<<1|1][sign] = sum[rt<<1|1][sign] = pre_max[rt<<1|1][sign] = suf_max[rt<<1|1][sign] = 0; 48 lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; 49 lazy[rt] = -1; 50 } 51 if(XOR[rt]) { 52 change(rt<<1); 53 change(rt<<1|1); 54 XOR[rt] = 0; 55 } 56 } 57 void build(int l, int r, int rt) { 58 XOR[rt] = 0, lazy[rt] = -1; 59 if(l == r) { 60 int sign; 61 scanf("%d", &sign); 62 sum[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = maxx[rt][sign] = 1; 63 sign^=1; 64 sum[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = maxx[rt][sign] = 0; 65 return ; 66 } 67 int m = l+r>>1; 68 build(lson); 69 build(rson); 70 pushUp(rt, 1, r-l+1); 71 pushUp(rt, 0, r-l+1); 72 } 73 void update(int L, int R, int l, int r, int rt, int sign) { 74 if(L<=l&&R>=r) { 75 if(sign == 2) { 76 change(rt); 77 } else { 78 lazy[rt] = sign; 79 sum[rt][sign] = maxx[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = (r-l+1); 80 sign ^= 1; 81 sum[rt][sign] = maxx[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = 0; 82 XOR[rt] = 0; 83 } 84 return ; 85 } 86 pushDown(rt, r-l+1); 87 int m = l+r>>1; 88 if(L<=m) 89 update(L, R, lson, sign); 90 if(R>m) 91 update(L, R, rson, sign); 92 pushUp(rt, 0, r-l+1); 93 pushUp(rt, 1, r-l+1); 94 } 95 int query(int L, int R, int l, int r, int rt, int sign) { 96 if(L<=l&&R>=r) { 97 if(sign) { 98 return maxx[rt][1]; 99 } else { 100 return sum[rt][1]; 101 } 102 } 103 pushDown(rt, r-l+1); 104 int m = l+r>>1, ret = 0; 105 if(sign) { 106 if(L<=m) 107 ret = query(L, R, lson, sign); 108 if(R>m) 109 ret = max(ret, query(L, R, rson, sign)); 110 ret = max(ret, min(R-m, pre_max[rt<<1|1][1])+min(m-L+1, suf_max[rt<<1][1])); 111 return ret; 112 } else { 113 if(L<=m) 114 ret += query(L, R, lson, sign); 115 if(R>m) 116 ret += query(L, R, rson, sign); 117 return ret; 118 } 119 } 120 int main() 121 { 122 int t, n, m, sign, x, y; 123 cin>>t; 124 while(t--) { 125 scanf("%d%d", &n, &m); 126 build(1, n, 1); 127 while(m--) { 128 scanf("%d%d%d", &sign, &x, &y); 129 if(sign <= 2) { 130 update(x+1, y+1, 1, n, 1, sign); 131 } else { 132 cout<<query(x+1, y+1, 1, n, 1, sign-3)<<endl; 133 } 134 } 135 } 136 }