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 }

 

posted on 2015-12-13 13:44  yohaha  阅读(134)  评论(0编辑  收藏  举报

导航