首页 > 代码库 > 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 线段树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。