hdu 3397 Sequence operation(线段树区间覆盖,区间合并)



Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
 

Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
 

Output
For each output operation , output the result.
 

Sample Input
  
  
1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
 

Sample Output
  
  
5 2 6 5
0 a b将区间[a,b]所有数全部变成0
1 a b将区间[a,b]所有数全部变成1
2 a b将区间[a,b]中所有数0 1互换,0变1,1变0
3 a b输出区间[a,b]中1的个数
4 a b输出区间[a,b]中最长连续1的个数





代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
	int l, r, sum;
	int ls1, rs1, ms1;
	int ls0, rs0, ms0;
	int flag1, flag2;
}tree[1000000];
int a[1000000];
void function(int id)
{
	swap(tree[id].ls0, tree[id].ls1);
	swap(tree[id].rs0, tree[id].rs1);
	swap(tree[id].ms0, tree[id].ms1);
	tree[id].sum = tree[id].r - tree[id].l + 1 - tree[id].sum;
}
void pushup(int id)
{
	if (tree[id].l == tree[id].r)
		return;
	tree[id].sum = tree[2 * id].sum + tree[2 * id + 1].sum;
	tree[id].ls0 = tree[2 * id].ls0, tree[id].rs0 = tree[2 * id + 1].rs0;
	tree[id].ls1 = tree[2 * id].ls1, tree[id].rs1 = tree[2 * id + 1].rs1;
	if (tree[id * 2].r - tree[2 * id].l + 1 == tree[2 * id].ls1)
		tree[id].ls1 += tree[2 * id + 1].ls1;
	if (tree[id * 2].r - tree[2 * id].l + 1 == tree[2 * id].ls0)
		tree[id].ls0 += tree[2 * id + 1].ls0;
	if (tree[2 * id + 1].r - tree[2 * id + 1].l + 1 == tree[id * 2 + 1].rs1)
		tree[id].rs1 += tree[2 * id].rs1;
	if (tree[2 * id + 1].r - tree[2 * id + 1].l + 1 == tree[id * 2 + 1].rs0)
		tree[id].rs0 += tree[2 * id].rs0;
	tree[id].ms1 = max(max(tree[2 * id].ms1, tree[2 * id + 1].ms1), tree[2 * id].rs1 + tree[2 * id + 1].ls1);
	tree[id].ms0 = max(max(tree[2 * id].ms0, tree[2 * id + 1].ms0), tree[2 * id].rs0 + tree[2 * id + 1].ls0);
}
void pushdown(int id)
{
	if (tree[id].l == tree[id].r)
		return;
	if (tree[id].flag1 != -1)
	{
		int len = tree[id].r - tree[id].l + 1;
		tree[2*id].flag1 = tree[2*id+1].flag1 = tree[id].flag1;
		tree[2*id].flag2 = tree[2*id+1].flag2 = 0;
		tree[2*id].ls0 = tree[2*id].rs0 = tree[2*id].ms0 = tree[id].flag1 ? 0 : (len + 1) / 2;
		tree[2*id].ls1 = tree[2*id].rs1 = tree[2*id].ms1 = tree[id].flag1 ? (len + 1) / 2 : 0;
		tree[2*id].sum = tree[id].flag1 ? (len + 1) / 2 : 0;
		tree[2*id+1].ls0 = tree[2*id+1].rs0 = tree[2*id+1].ms0 = tree[id].flag1 ? 0 : len / 2;
		tree[2*id+1].ls1 = tree[2*id+1].rs1 = tree[2*id+1].ms1 = tree[id].flag1 ? len / 2 : 0;
		tree[2*id+1].sum = tree[id].flag1 ? len / 2 : 0;
		tree[id].flag1 = -1;
	}
	if (tree[id].flag2 != 0)
	{
		tree[id].flag2 = 0;
		tree[2 * id].flag2 ^= 1, tree[2 * id + 1].flag2 ^= 1;
		function(2 * id), function(2 * id + 1);
	}
}
void build(int id, int l, int r)
{
	tree[id].l = l, tree[id].r = r;
	tree[id].flag1 = -1, tree[id].flag2 = 0;
	if (l == r)
	{
		tree[id].flag1=tree[id].sum = a[l];
		if (a[l] == 0)
		{
			tree[id].ms0 = tree[id].ls0 = tree[id].rs0 = 1;
			tree[id].ms1 = tree[id].ls1 = tree[id].rs1 = 0;
		}
		if (a[l] == 1)
		{
			tree[id].ms0 = tree[id].ls0 = tree[id].rs0 = 0;
			tree[id].ms1 = tree[id].ls1 = tree[id].rs1 = 1;
		}
		return;
	}
	int mid = (l + r) / 2;
	build(2 * id, l, mid);
	build(2 * id + 1, mid + 1, r);
	pushup(id);
}
void update(int id, int l, int r, int t)
{
	pushdown(id);
	if (l <= tree[id].l&&tree[id].r <= r)
	{
		int len = tree[id].r - tree[id].l + 1;
		if (t == 0)
		{
			tree[id].ls1 = tree[id].rs1 = tree[id].ms1 = tree[id].flag1 = tree[id].sum = 0;
			tree[id].ls0 = tree[id].rs0 = tree[id].ms0 = len;
		}
		if (t == 1)
		{
			tree[id].ls0 = tree[id].rs0 = tree[id].ms0 = 0, tree[id].flag1 = 1;
			tree[id].sum = tree[id].ls1 = tree[id].rs1 = tree[id].ms1 = len;
		}
		if (t == 2)
		{
			tree[id].flag2 = 1;
			function(id);
		}
		return;
	}
	if (l <= tree[2 * id].r) update(2 * id, l, r, t);
	if (r >= tree[2 * id + 1].l) update(2 * id + 1, l, r, t);
	pushup(id);
}
int query(int id, int l, int r, int t)
{
	pushdown(id);
	if (l <= tree[id].l&&tree[id].r <= r)
	{
		if (t == 3) return tree[id].sum;
		else return tree[id].ms1;
	}
	if (r <= tree[2 * id].r) return query(2 * id, l, r, t);
	if (l >= tree[2 * id + 1].l) return query(2 * id + 1, l, r, t);
	if (t == 3) return query(2 * id, l, tree[2 * id].r, t) + query(2 * id + 1, tree[2 * id + 1].l, r, t);
	int ans1 = min(tree[2 * id].rs1, tree[2 * id].r - l + 1) + min(tree[2 * id + 1].ls1, r - tree[2 * id + 1].l + 1);
	int ans2 = max(query(2 * id, l, tree[2 * id].r, t), query(2 * id + 1, tree[2 * id + 1].l, r, t));
	return max(ans1, ans2);
}
int main()
{
	int t, l, r, t1, n, m;
	scanf("%d", &t1);
	while (t1--)
	{
		memset(a, -1, sizeof(a));
		scanf("%d%d", &n, &m);
		for (int i = 1;i <= n;i++)
			scanf("%d", &a[i]);
		build(1, 1, n);
		while (m--)
		{
			scanf("%d%d%d", &t, &l, &r);		  l++, r++;
			if (t < 3)
				update(1, l, r, t);
			else printf("%d\n", query(1, l, r, t));
		}
	}
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值