您的位置:首页 > 其它

hdu 3911 Black And White (线段树)

2017-07-19 21:25 344 查看

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=
4000
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: