首页 > 代码库 > HDOJ 3911 线段树

HDOJ 3911 线段树

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3911

题意:

给出01串 1代表黑色 0代表白色  

0 a b:询问[a,b]中1的连续最大长度  

1 a,b:把[a,b]区间的0->1 1->0  

题解:

lsum1[],rsum1[],msum1[]分别表示区间左起连续1的最大长度,右起连续1的最大长度,区间1的最大连续长度  

lsum0[],rsum0[],msum0[]分别表示区间左起连续0的最大长度,右起连续0的最大长度,区间连续0的最大连续长度  

0 a b:交换 0和1的lsum[] rsum[] msum[]; ROX[]表示需要向儿子更新 两次更新=不变  

代码:

  1 #include <map>
  2 #include <set>
  3 #include <cmath>
  4 #include <queue>
  5 #include <stack>
  6 #include <cstdio>
  7 #include <string>
  8 #include <vector>
  9 #include <cstdlib>
 10 #include <cstring>
 11 #include <sstream>
 12 #include <iostream>
 13 #include <algorithm>
 14 #include <functional>
 15 using namespace std;
 16 #define rep(i,a,n) for (int i=a;i<n;i++)
 17 #define per(i,a,n) for (int i=n-1;i>=a;i--)
 18 #define all(x) (x).begin(),(x).end()
 19 #define pb push_back
 20 #define mp make_pair
 21 #define lson l,m,rt<<1  
 22 #define rson m+1,r,rt<<1|1 
 23 typedef long long ll;
 24 typedef vector<int> VI;
 25 typedef pair<int, int> PII;
 26 const ll MOD = 1e9 + 7;
 27 const int INF = 0x3f3f3f3f;
 28 const int MAXN = 1e5 + 7;
 29 // head
 30 
 31 int rox[MAXN << 2];
 32 int lsum1[MAXN << 2], rsum1[MAXN << 2], msum1[MAXN << 2];
 33 int lsum0[MAXN << 2], rsum0[MAXN << 2], msum0[MAXN << 2];
 34 
 35 void pushup(int rt, int m) {
 36     lsum1[rt] = lsum1[rt << 1], rsum1[rt] = rsum1[rt << 1 | 1];
 37     if (lsum1[rt << 1] == m - (m >> 1)) lsum1[rt] += lsum1[rt << 1 | 1];
 38     if (rsum1[rt << 1 | 1] == m >> 1) rsum1[rt] += rsum1[rt << 1];
 39     msum1[rt] = max(max(msum1[rt << 1], msum1[rt << 1 | 1]), rsum1[rt << 1] + lsum1[rt << 1 | 1]);
 40     lsum0[rt] = lsum0[rt << 1], rsum0[rt] = rsum0[rt << 1 | 1];
 41     if (lsum0[rt << 1] == m - (m >> 1)) lsum0[rt] += lsum0[rt << 1 | 1];
 42     if (rsum0[rt << 1 | 1] == m >> 1) rsum0[rt] += rsum0[rt << 1];
 43     msum0[rt] = max(max(msum0[rt << 1], msum0[rt << 1 | 1]), rsum0[rt << 1] + lsum0[rt << 1 | 1]);
 44 }
 45 
 46 void pushdown(int rt, int m) {
 47     if (rox[rt]) {
 48         rox[rt << 1] ^= 1, rox[rt << 1 | 1] ^= 1;
 49         swap(lsum0[rt << 1], lsum1[rt << 1]);
 50         swap(rsum0[rt << 1], rsum1[rt << 1]);
 51         swap(msum0[rt << 1], msum1[rt << 1]);
 52         swap(lsum0[rt << 1 | 1], lsum1[rt << 1 | 1]);
 53         swap(rsum0[rt << 1 | 1], rsum1[rt << 1 | 1]);
 54         swap(msum0[rt << 1 | 1], msum1[rt << 1 | 1]);
 55         rox[rt] = 0;
 56     }
 57 }
 58 
 59 void build(int l, int r, int rt) {
 60     rox[rt] = 0;
 61     if (l == r) {
 62         int c;
 63         scanf("%d", &c);
 64         lsum1[rt] = rsum1[rt] = msum1[rt] = c;
 65         lsum0[rt] = rsum0[rt] = msum0[rt] = c ^ 1;
 66         return;
 67     }
 68     int m = (l + r) >> 1;
 69     build(lson);
 70     build(rson);
 71     pushup(rt, l - r + 1);
 72 }
 73 
 74 void update(int L, int R, int l, int r, int rt) {
 75     if (L <= l && r <= R) {
 76         rox[rt] ^= 1;
 77         swap(lsum0[rt], lsum1[rt]);
 78         swap(rsum0[rt], rsum1[rt]);
 79         swap(msum0[rt], msum1[rt]);
 80         return;
 81     }
 82     pushdown(rt, r - l + 1);
 83     int m = (l + r) >> 1;
 84     if (L <= m) update(L, R, lson);
 85     if (R > m) update(L, R, rson);
 86     pushup(rt, r - l + 1);
 87 }
 88 
 89 int query(int L, int R, int l, int r, int rt) {
 90     if (L <= l && r <= R) return msum1[rt];
 91     pushdown(rt, r - l + 1);
 92     int m = (l + r) >> 1;
 93     int ret;
 94     if (m >= R) ret = query(L, R, lson);
 95     else if (m < L) ret = query(L, R, rson);
 96     else {
 97         ret = max(query(L, R, lson), query(L, R, rson));
 98         int t1 = min(m - L + 1, rsum1[rt << 1]);
 99         int t2 = min(R - m, lsum1[rt << 1 | 1]);
100         ret = max(ret, t1 + t2);
101     }
102     return ret;
103 }
104 
105 int main() {
106     int n, m;
107     while (cin >> n) {
108         build(1, n, 1);
109         cin >> m;
110         while (m--) {
111             int a, b, c;
112             scanf("%d%d%d", &a, &b, &c);
113             if (a) update(b, c, 1, n, 1);
114             else printf("%d\n", query(b, c, 1, n, 1));
115         }
116     }
117     return 0;
118 }

 

HDOJ 3911 线段树