[SCOI2010]序列操作

来源:互联网 发布:秦皇岛2015年旅游数据 编辑:程序博客网 时间:2024/06/07 23:21

傻逼线段树水题……调了好久

结点维护3个标记和几个信息……

代码实在丑233

Code:

#include <cstdio>#include <algorithm>#include <cstring>#include <iostream>using namespace std;#define N 1<<17struct Segment_Tree{int l, r, lazy, rest0, rest1, l1max, r1max, max1, l0max, r0max, max0, num, num0, num1, now;}T[N<<2];struct doubi{int x, l, r;void clear(){x = l = r = 0;}};char c;int a[N], n, m;inline void read(int &x){for (c = getchar();c > '9' || c < '0';c = getchar());for (x = 0;c >= '0' && c <= '9';c = getchar())x = (x << 3) + (x << 1) + c - '0';}inline void ch0(int o){T[o].now = 0;T[o].max0 = T[o].l0max = T[o].r0max = T[o].num0 = T[o].num;T[o].max1 = T[o].l1max = T[o].r1max = T[o].num1 = 0;}inline void ch1(int o){T[o].now = 1;T[o].max1 = T[o].l1max = T[o].r1max = T[o].num1 = T[o].num;T[o].max0 = T[o].l0max = T[o].r0max = T[o].num0 = 0;}inline void Updateo(int o){if (T[o<<1].now == T[o<<1|1].now && T[o<<1].now != -1){if (T[o<<1].now)ch1(o);elsech0(o);}else{T[o].now = -1;if (T[o<<1].now == 0)T[o].l0max = T[o<<1].l0max + T[o<<1|1].l0max;elseT[o].l0max = T[o<<1].l0max;if (T[o<<1].now == 1)T[o].l1max = T[o<<1].l1max + T[o<<1|1].l1max;elseT[o].l1max = T[o<<1].l1max;if (T[o<<1|1].now == 0)T[o].r0max = T[o<<1].r0max + T[o<<1|1].r0max;elseT[o].r0max = T[o<<1|1].r0max;if (T[o<<1|1].now == 1)T[o].r1max = T[o<<1].r1max + T[o<<1|1].r1max;elseT[o].r1max = T[o<<1|1].r1max;T[o].max0 = max(T[o<<1].r0max + T[o<<1|1].l0max, max(T[o<<1].max0, T[o<<1|1].max0));T[o].max1 = max(T[o<<1].r1max + T[o<<1|1].l1max, max(T[o<<1].max1, T[o<<1|1].max1));T[o].num0 = T[o<<1].num0 + T[o<<1|1].num0;T[o].num1 = T[o<<1].num1 + T[o<<1|1].num1;}}inline void build(int o, int l, int r){T[o].l = l, T[o].r = r;T[o].num = r - l + 1;if (l == r){T[o].now = a[l];if (a[l])T[o].max1 = T[o].l1max = T[o].r1max = T[o].num1 = 1;elseT[o].max0 = T[o].l0max = T[o].r0max = T[o].num0 = 1;return;}int mid = (l + r) >> 1;build(o<<1, l, mid), build(o<<1|1, mid+1, r);Updateo(o);}inline void S(int o){if (T[o].now != -1)T[o].now ^= 1;swap(T[o].rest0, T[o].rest1);swap(T[o].l0max, T[o].l1max);swap(T[o].r0max, T[o].r1max);swap(T[o].max0, T[o].max1);swap(T[o].num0, T[o].num1);}inline void Pushdown(int o){if (T[o].lazy){T[o].lazy ^= 1;if (T[o].l != T[o].r){T[o<<1].lazy ^= 1, T[o<<1|1].lazy ^= 1;S(o<<1), S(o<<1|1);}}if (T[o].rest0){T[o].rest0 = 0;if (T[o].l != T[o].r){ch0(o<<1), ch0(o<<1|1);T[o<<1].rest0 = T[o<<1|1].rest0 = 1;T[o<<1].rest1 = T[o<<1|1].rest1 = 0;}}if (T[o].rest1){T[o].rest1 = 0;if (T[o].l != T[o].r){ch1(o<<1), ch1(o<<1|1);T[o<<1].rest0 = T[o<<1|1].rest0 = 0;T[o<<1].rest1 = T[o<<1|1].rest1 = 1;}}}inline doubi Query(int o, int l, int r, int flag){doubi res, resl, resr;bool L(0), R(0);res.clear(), resl.clear(), resr.clear();if (l <= T[o].l && T[o].r <= r){if (flag == 1)res.x = T[o].num1;else{res.x = T[o].max1;res.l = T[o].l1max;res.r = T[o].r1max;}return res;}Pushdown(o);int mid = (T[o].l + T[o].r) >> 1;if (l <= mid){L = 1;resl = Query(o<<1, l, r, flag);if (flag == 1)res.x += resl.x;}if (r > mid){R = 1;resr = Query(o<<1|1, l, r, flag);if (flag == 1)res.x += resr.x;}if (flag == 1)return res;res.x = max(resl.r + resr.l, max(resl.x, resr.x));if (L && R){ if (T[o<<1].now == 1)res.l = resl.l + resr.l;elseres.l = resl.l;if (T[o<<1|1].now == 1)res.r = resr.r + resl.r;elseres.r = resr.r;}else{if (L)return resl;if (R)return resr;}return res;}inline void Update(int o, int l, int r, int flag){if (l <= T[o].l && T[o].r <= r){if (flag == 2)S(o), T[o].lazy ^= 1;else{if (T[o].lazy)Pushdown(o);if (flag)T[o].rest0 = 0, T[o].rest1 = 1, ch1(o);elseT[o].rest1 = 0, T[o].rest0 = 1, ch0(o);}return;}Pushdown(o);int mid = (T[o].l + T[o].r) >> 1; if (l <= mid)Update(o<<1, l, r, flag);if (r > mid)Update(o<<1|1, l, r, flag);Updateo(o);}int main(){int i, k, l, r;read(n), read(m);for (i = 1;i <= n; ++i)read(a[i]);build(1, 1, n);while (m--){doubi ans;read(k), read(l), read(r);l++, r++;if (k == 0)Update(1, l, r, 0);elseif (k == 1)Update(1, l, r, 1);elseif (k == 2)Update(1, l, r, 2);elseif (k == 3)ans = Query(1, l, r, 1), printf("%d\n", max(ans.x, max(ans.l, ans.r)));elseif (k == 4)ans = Query(1, l, r, 2), printf("%d\n", max(ans.x, max(ans.l, ans.r)));}return 0;}


0 0
原创粉丝点击