hdu 3911 Black And White (线段树)
来源:互联网 发布:四氧化三铁化学式算法 编辑:程序博客网 时间:2024/05/29 02:12
Problem Description
There are a bunch of stones on the beach; Stone color is white or black. Little Sheep has a magic brush, she can change the color of a continuous stone, black to white, white to black. Little Sheep like black very much, so she want to know the longest period of consecutive black stones in a range [i, j].
Input
There are multiple cases, the first line of each case is an integer n(1<= n <= 10^5), followed by n integer 1 or 0(1 indicates black stone and 0 indicates white stone), then is an integer M(1<=M<=10^5) followed by M operations formatted as x i j(x = 0 or 1) , x=1 means change the color of stones in range[i,j], and x=0 means ask the longest period of consecutive black stones in range[i,j]
Output
When x=0 output a number means the longest length of black stones in range [i,j].
Sample Input
4
1 0 1 0
5
0 1 4
1 2 3
0 1 4
1 3 3
0 4 4
Sample Output
1
2
0
题意
给你一些01序列,再给你一些询问。当询问为1的时候,把给定区间内所有的0变为1,1边为0,当询问为0的时候,输出所求区间中最长的连续的1的个数。
不想写题解,写这题不是要写这题,而是为了练模板……背叛指针线段树转投数组之中(但其实还是二昏二昏的)。……还有一个区间合并?
代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct Node { int flag, lmax0, lmax1, rmax0, rmax1, imax0, imax1, l, r; } tree[1000010];int a[1000010], n, m, x, l, r;void pushup(int root) { int ls = root << 1, rs = root << 1 | 1; int llen=tree[ls].r - tree[ls].l + 1; int rlen=tree[rs].r - tree[rs].l + 1; tree[root].lmax1=tree[ls].lmax1; if(tree[ls].lmax1 == llen) tree[root].lmax1 += tree[rs].lmax1; tree[root].rmax1=tree[rs].rmax1; if(tree[rs].rmax1 == rlen) tree[root].rmax1 += tree[ls].rmax1; int m1 = max(tree[ls].imax1, tree[rs].imax1); int m2 = tree[rs].lmax1 + tree[ls].rmax1; tree[root].imax1 = max(m1, m2); tree[root].lmax0 = tree[ls].lmax0; if(tree[ls].lmax0 == llen) tree[root].lmax0 += tree[rs].lmax0; tree[root].rmax0 = tree[rs].rmax0; if(tree[rs].rmax0 == rlen) tree[root].rmax0 += tree[ls].rmax0; m1 = max(tree[ls].imax0, tree[rs].imax0); m2 = tree[rs].lmax0 + tree[ls].rmax0; tree[root].imax0 = max(m1, m2);}void pushdown(int root) { if(tree[root].flag) { int ls = root << 1, rs = root << 1 | 1; tree[ls].flag ^= 1; swap(tree[ls].lmax1, tree[ls].lmax0); swap(tree[ls].rmax1, tree[ls].rmax0); swap(tree[ls].imax1, tree[ls].imax0); tree[rs].flag ^= 1; swap(tree[rs].lmax1, tree[rs].lmax0); swap(tree[rs].rmax1, tree[rs].rmax0); swap(tree[rs].imax1, tree[rs].imax0); tree[root].flag = 0; }}void build(int root, int l, int r) { tree[root].l = l, tree[root].r = r; if(l == r) { if(a[l]) { tree[root].lmax0 = tree[root].rmax0 = tree[root].imax0 = a[l]^1; tree[root].lmax1 = tree[root].rmax1 = tree[root].imax1 = a[l]&1; } else { tree[root].lmax0 = tree[root].rmax0 = tree[root].imax0 = 1; tree[root].lmax1 = tree[root].rmax1 = tree[root].imax1 = 0; } tree[root].flag = 0; return ; } int mid = (l + r) >> 1; build(root << 1, l, mid); build(root << 1 | 1,mid + 1, r); tree[root].flag = 0; pushup(root);}void modify(int root, int L, int R) { int l = tree[root].l, r = tree[root].r; if(l >= L && r <= R) { tree[root].flag ^= 1; swap(tree[root].lmax1, tree[root].lmax0); swap(tree[root].rmax1, tree[root].rmax0); swap(tree[root].imax1, tree[root].imax0); return ; } int mid = (l + r) >> 1; pushdown(root); if(R <= mid) modify(root << 1, L, R); else if(L > mid) modify(root << 1 | 1, L, R); else { modify(root << 1, L, mid); modify(root << 1 | 1, mid + 1, R); } pushup(root);}int query(int root,int L,int R){ int l = tree[root].l, r = tree[root].r; if(l == L && r == R) return tree[root].imax1; pushdown(root); int mid = (l + r) >> 1; if(R <= mid) return query(root << 1, L, R); if(L > mid) return query(root << 1 | 1, L, R); int ll = query(root << 1, L, mid); int rl = query(root << 1 | 1, mid + 1, R); int a = tree[root << 1].rmax1; if(a > tree[root << 1].r - L + 1) a = tree[root << 1].r - L + 1; int b = tree[root << 1 | 1].lmax1; if(b > R - tree[root << 1 | 1].l + 1) b = R - tree[root << 1 | 1].l + 1; int ans = max(ll, max(rl, a + b)); return ans;}int main() { while(~ scanf("%d", &n)){ for(register int i = 1; i <= n; i ++) scanf("%d", &a[i]); build(1, 1, n); scanf("%d", &m); for(register int i = 1; i <= m; i ++){ scanf("%d %d %d", &x, &l, &r); if(x == 0) printf("%d\n", query(1, l, r)); else if(x == 1) modify(1, l, r); } } return 0;}
- HDU--3911[Black And White] 线段树
- hdu 3911 Black And White 线段树
- HDU 3911 Black And White 线段树
- hdu 3911 Black And White(线段树)
- hdu 3911 Black And White(线段树)
- HDU 3911 Black And White(线段树区间合并)
- HDU 3911 Black And White (线段树区间更新)
- hdu 3911 Black And White (线段树)
- hdu 3911 Black And White 区间合并 线段树
- hdu 3911 Black And White 线段树区间合并
- hdu 3911 black and white 线段树区间合并
- hdu 3911 Black and White 线段树维护01序列
- HDU 3911 Black And White(线段树区间合并+lazy操作)
- hdu 3911 Black and White
- hdu 3911 Black And White
- hdu 3911 Black And White
- HDU 3911 Black And White
- HDU 3911 Black And White
- Qt经典出错信息之QApplication: No such file or directory
- 分布式java应用(二)
- 数组补充 及二位数组 排序方法 冒泡
- 冒泡排序
- 一分钟了解“Matlab统计数值频率和个数tabulate”
- hdu 3911 Black And White (线段树)
- matplotlib 次坐标轴
- NOIP2013 Day2 T3 华容道
- 线程池使用
- Android 硬件加速
- QT focusInEvent 事件
- 一分钟了解“do and has done”
- setInterval()函数的用法心得
- PHP中的字符串格式化输出函数和字符串比较函数