首页 > 代码库 > Hdu3397Sequence operation线段树
Hdu3397Sequence operation线段树
#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>#include<math.h>#include<vector>using namespace std;const int maxn = 111111;int color[maxn << 2], sign[maxn << 2];int sum[maxn << 2], lsum[maxn << 2], rsum[maxn << 2];int sum1[maxn << 2], lsum1[maxn << 2], rsum1[maxn << 2];int ans[maxn << 2];#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1void below(int rt, int m){ if (~color[rt]) color[rt] ^= 1; else sign[rt] ^= 1; ans[rt] = m - ans[rt]; swap(sum[rt], sum1[rt]); swap(lsum[rt], lsum1[rt]); swap(rsum[rt], rsum1[rt]);}void down(int rt, int m){ if (~color[rt]){ sign[rt << 1] = sign[rt << 1 | 1] = 0; color[rt << 1] = color[rt << 1 | 1] = color[rt]; if (color[rt] == 1){ ans[rt << 1] = m - (m >> 1); sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = m - (m >> 1); sum1[rt << 1] = rsum1[rt << 1] = lsum1[rt << 1] = 0; ans[rt << 1 | 1] = (m >> 1); sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = (m >> 1); sum1[rt << 1 | 1] = rsum1[rt << 1 | 1] = lsum1[rt << 1 | 1] = 0; } if (color[rt] == 0){ ans[rt << 1] = ans[rt << 1 | 1] = 0; sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = 0; sum1[rt << 1] = lsum1[rt << 1] = rsum1[rt << 1] = (m - (m >> 1)); sum1[rt << 1 | 1] = lsum1[rt << 1 | 1] = rsum1[rt << 1 | 1] = (m >> 1); } color[rt] = -1; } if (sign[rt]){ below(rt << 1, (m - (m >> 1))); below(rt << 1 | 1, (m >> 1)); sign[rt] = 0; }}void up(int rt, int m){ ans[rt] = ans[rt << 1] + ans[rt << 1 | 1]; lsum[rt] = lsum[rt << 1]; rsum[rt] = rsum[rt << 1 | 1]; if (lsum[rt] == (m - (m >> 1))) lsum[rt] += lsum[rt << 1 | 1]; if (rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt << 1]; sum[rt] = max(max(sum[rt << 1], sum[rt << 1 | 1]), rsum[rt << 1] + lsum[rt << 1 | 1]); lsum1[rt] = lsum1[rt << 1]; rsum1[rt] = rsum1[rt << 1 | 1]; if (lsum1[rt] == (m - (m >> 1))) lsum1[rt] += lsum1[rt << 1 | 1]; if (rsum1[rt] == (m >> 1)) rsum1[rt] += rsum1[rt << 1]; sum1[rt] = max(max(sum1[rt << 1], sum1[rt << 1 | 1]), rsum1[rt << 1] + lsum1[rt << 1 | 1]);}void build(int l, int r, int rt){ color[rt] = -1; sign[rt] = 0; if (l == r){ scanf("%d", &ans[rt]); if (ans[rt]) sum[rt] = lsum[rt] = rsum[rt] = 1, lsum1[rt] = rsum1[rt] = sum1[rt] = 0; else sum1[rt] = lsum1[rt] = rsum1[rt] = 1, sum[rt] = lsum[rt] = rsum[rt] = 0; return; } int mid = (l + r) >> 1; build(lson); build(rson); up(rt, r - l + 1);}void update(int L, int R, int add, int l, int r, int rt){ if (L <= l&&r <= R){ if (add == 1){ color[rt] = 1; sign[rt] = 0; ans[rt] = r - l + 1; sum[rt] = lsum[rt] = rsum[rt] = r - l + 1; sum1[rt] = lsum1[rt] = rsum1[rt] = 0; } if (add == 0){ color[rt] = 0; sign[rt] = 0; ans[rt] = 0; sum[rt] = lsum[rt] = rsum[rt] = 0; sum1[rt] = lsum1[rt] = rsum1[rt] = r - l + 1; } if (add == -1) below(rt,r-l+1); return; } int mid = (l + r) >> 1; down(rt, r - l + 1); if (L <= mid) update(L, R, add, lson); if (R > mid) update(L, R, add, rson); up(rt, r - l + 1);}int ask(int L, int R, int l, int r, int rt){ if (L <= l&&r <= R) return ans[rt]; down(rt, r - l + 1); int mid = (l + r) >> 1; int ret = 0; if (L <= mid) ret += ask(L, R, lson); if (R > mid) ret += ask(L, R, rson); return ret;}int ask1(int L, int R, int l, int r, int rt){ if (L <= l&&r <= R) return sum[rt]; int mid = (l + r) >> 1; down(rt, r - l + 1); int ret = 0; ret = min(mid - L + 1, rsum[rt << 1]) + min(R - mid, lsum[rt << 1 | 1]); if (L <= mid) ret = max(ret, ask1(L,R,lson)); if (R > mid) ret = max(ret, ask1(L,R,rson)); return ret;}int main(){ int Icase; int n; int m; int a; int b; int c; scanf("%d", &Icase); while (Icase--){ scanf("%d%d", &n, &m); build(1, n, 1); for (int i = 0; i < m; i++){ //printf("jijidajiji%d\n", sum[1]); scanf("%d%d%d", &a, &b, &c); b++; c++; if (a == 0) update(b, c, 0, 1, n, 1); if (a == 1) update(b, c, 1, 1, n, 1); if (a == 2) update(b, c, -1, 1, n, 1); if (a == 3){ int t = ask(b, c, 1, n, 1); printf("%d\n", t); } if (a == 4){ int t = ask1(b, c, 1, n, 1); //printf("chaojixiaojiji %d\n", ask1(3, 3, 1, n, 1)); printf("%d\n", t); } } } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。