hdu 3397(区间合并)
2015-09-03 17:13
471 查看
题意:有一个长度为n的序列,由0和1组成,然后五种操作,0 a b表示把区间[a,b]内的数字全部设置为0,1 a b表示把区间[a,b]内的数字全部设置为1,2 a b表示把区间[a,b]的数字0换为1,1换为0,3 a b表示输出区间[a,b]中1的个数,4 a b表示输出区间[a,b]中连续的1的最大长度。
题解:因为要输出连续是1的最大长度,肯定合并的时候要注意。线段树维护左右端点延伸的0的数量lenl0,lenr0,还有左右端点延伸的1的数量lenl1,lenr1,和整个区间最长连续0和1的数量len0,len1,以及区间内0和1的数量num0,num1。这样操作2可以直接把所有有关0和1的维护的值全部互换。
题解:因为要输出连续是1的最大长度,肯定合并的时候要注意。线段树维护左右端点延伸的0的数量lenl0,lenr0,还有左右端点延伸的1的数量lenl1,lenr1,和整个区间最长连续0和1的数量len0,len1,以及区间内0和1的数量num0,num1。这样操作2可以直接把所有有关0和1的维护的值全部互换。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100005; struct Tree { int lenl1, lenr1, len1, lenl0, lenr0, len0, num1, num0; int flag1, flag2; }tree[N << 2]; int n, m, A ; void pushup(int k, int left, int right) { int mid = (left + right) / 2; tree[k].lenl0 = tree[k * 2].lenl0; tree[k].lenl1 = tree[k * 2].lenl1; tree[k].lenr0 = tree[k * 2 + 1].lenr0; tree[k].lenr1 = tree[k * 2 + 1].lenr1; tree[k].num1 = tree[k * 2].num1 + tree[k * 2 + 1].num1; tree[k].num0 = tree[k * 2].num0 + tree[k * 2 + 1].num0; tree[k].len0 = max(tree[k * 2].lenr0 + tree[k * 2 + 1].lenl0, max(tree[k * 2].len0, tree[k * 2 + 1].len0)); tree[k].len1 = max(tree[k * 2].lenr1 + tree[k * 2 + 1].lenl1, max(tree[k * 2].len1, tree[k * 2 + 1].len1)); if (tree[k * 2].lenl0 == mid - left + 1) tree[k].lenl0 += tree[k * 2 + 1].lenl0; if (tree[k * 2].lenl1 == mid - left + 1) tree[k].lenl1 += tree[k * 2 + 1].lenl1; if (tree[k * 2 + 1]. lenr0 == right - mid) tree[k].lenr0 += tree[k * 2].lenr0; if (tree[k * 2 + 1]. lenr1 == right - mid) tree[k].lenr1 += tree[k * 2].lenr1; } void pushdown(int k, int left, int right) { if (tree[k].flag1 != -1) { int mid = (left + right) / 2; tree[k * 2].flag1 = tree[k * 2 + 1].flag1 = tree[k].flag1; if (tree[k].flag1 == 0) { tree[k * 2].lenl1 = tree[k * 2].lenr1 = tree[k * 2].len1 = tree[k * 2].num1 = 0; tree[k * 2 + 1].lenl1 = tree[k * 2 + 1].lenr1 = tree[k * 2 + 1].len1 = tree[k * 2 + 1].num1 = 0; tree[k * 2].num0 = tree[k * 2].lenl0 = tree[k * 2].lenr0 = tree[k * 2].len0 = mid - left + 1; tree[k * 2 + 1].num0 = tree[k * 2 + 1].lenl0 = tree[k * 2 + 1].lenr0 = tree[k * 2 + 1].len0 = right - mid; } else if (tree[k].flag1 == 1) { tree[k * 2].lenl0 = tree[k * 2].lenr0 = tree[k * 2].len0 = tree[k * 2].num0 = 0; tree[k * 2 + 1].lenl0 = tree[k * 2 + 1].lenr0 = tree[k * 2 + 1].len0 = tree[k * 2 + 1].num0 = 0; tree[k * 2].num1 = tree[k * 2].lenl1 = tree[k * 2].lenr1 = tree[k * 2].len1 = mid - left + 1; tree[k * 2 + 1].num1 = tree[k * 2 + 1].lenl1 = tree[k * 2 + 1].lenr1 = tree[k * 2 + 1].len1 = right - mid; } tree[k].flag1 = -1; tree[k * 2].flag2 = tree[k * 2 + 1].flag2 = 0; } if (tree[k].flag2) { tree[k * 2].flag2 ^= tree[k].flag2; tree[k * 2 + 1].flag2 ^= tree[k].flag2; swap(tree[k * 2].num0, tree[k * 2].num1); swap(tree[k * 2 + 1].num0, tree[k * 2 + 1].num1); swap(tree[k * 2].lenl0, tree[k * 2].lenl1); swap(tree[k * 2 + 1].lenl0, tree[k * 2 + 1].lenl1); swap(tree[k * 2].lenr0, tree[k * 2].lenr1); swap(tree[k * 2 + 1].lenr0, tree[k * 2 + 1].lenr1); swap(tree[k * 2].len0, tree[k * 2].len1); swap(tree[k * 2 + 1].len0, tree[k * 2 + 1].len1); tree[k].flag2 = 0; } } void build(int k, int left, int right) { tree[k].flag1 = -1; tree[k].flag2 = 0; if (left == right) { if (A[left] == 1) { tree[k].num1 = tree[k].len1 = tree[k].lenl1 = tree[k].lenr1 = 1; tree[k].num0 = tree[k].len0 = tree[k].lenl0 = tree[k].lenr0 = 0; } else { tree[k].num1 = tree[k].len1 = tree[k].lenl1 = tree[k].lenr1 = 0; tree[k].num0 = tree[k].len0 = tree[k].lenl0 = tree[k].lenr0 = 1; } return; } int mid = (left + right) / 2; build(k * 2, left, mid); build(k * 2 + 1, mid + 1, right); pushup(k, left, right); } void modify(int k, int left, int right, int l, int r, int flag_1, int flag_2) { if (l <= left && right <= r) { if (flag_1 == 0) { tree[k].flag1 = tree[k].flag2 = flag_1; tree[k].num0 = tree[k].len0 = tree[k].lenl0 = tree[k].lenr0 = right - left + 1; tree[k].num1 = tree[k].len1 = tree[k].lenl1 = tree[k].lenr1 = 0; } else if (flag_1 == 1) { tree[k].flag1 = flag_1; tree[k].flag2 = 0; tree[k].num1 = tree[k].len1 = tree[k].lenl1 = tree[k].lenr1 = right - left + 1; tree[k].num0 = tree[k].len0 = tree[k].lenl0 = tree[k].lenr0 = 0; } else { tree[k].flag2 ^= flag_2; swap(tree[k].num0, tree[k].num1); swap(tree[k].len0, tree[k].len1); swap(tree[k].lenl0, tree[k].lenl1); swap(tree[k].lenr0, tree[k].lenr1); } return; } pushdown(k, left, right); int mid = (left + right) / 2; if (l <= mid) modify(k * 2, left, mid, l, r, flag_1, flag_2); if (r > mid) modify(k * 2 + 1, mid + 1, right, l, r, flag_1, flag_2); pushup(k, left, right); } int query(int k, int left, int right, int l, int r, int flag) { if (l <= left && right <= r) { if (flag == 1) return tree[k].num1; return tree[k].len1; } pushdown(k, left, right); int mid = (left + right) / 2; if (r <= mid) return query(k * 2, left, mid, l, r, flag); if (l > mid) return query(k * 2 + 1, mid + 1, right, l, r, flag); int res; int temp1 = query(k * 2, left, mid, l, mid, flag); int temp2 = query(k * 2 + 1, mid + 1, right, mid + 1, r, flag); if (!flag) { int temp3 = min(mid - l + 1, tree[k * 2].lenr1); int temp4 = min(r - mid, tree[k * 2 + 1].lenl1); res = max(max(temp1, temp2), temp3 + temp4); } else res = temp1 + temp2; return res; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &A[i]); build(1, 0, n - 1); int op, a, b; while (m--) { scanf("%d%d%d", &op, &a, &b); if (op == 0) modify(1, 0, n - 1, a, b, 0, 0); else if (op == 1) modify(1, 0, n - 1, a, b, 1, 0); else if (op == 2) modify(1, 0, n - 1, a, b, -1, 1); else if (op == 3) printf("%d\n", query(1, 0, n - 1, a, b, 1)); else printf("%d\n", query(1, 0, n - 1, a, b, 0)); } } return 0; }
相关文章推荐
- Hybrid App
- #牛客#代码实现:字符串的匹配、字符串的交错组成、纸牌博弈、表达式组合
- 消除: warning C4996: 'sprintf': This function or variable may be unsafe. Consider 的方法
- UITextFiledView页面之间的相互传值
- Tomcat - JNDI 配置
- 求子数组的最大和
- Unity3d-Socket之龙一编年史network.dll分析(2)-> CNetLogger
- 条款03 use const whenever possible
- ESB-Mule-demo-实例
- Unity3d-Socket之龙一编年史network.dll分析(2)-> CNetLogger
- LSM树以及在hbase中的应用
- NOIP 马拦过河卒
- bzoj2594
- 用了17年的Google Logo大改了
- hdu1060 Leftmost Digit
- Android开发之自定义控件与属性动画Animation的结合使用
- UvaLive 3709 Hard Life(最大密度子图)
- Schema约束
- bzoj2594
- 华为oj_学英语