hdu 1540 Tunnel Warfare(线段树 + 区间合并)

题目链接:hdu 1540

题目大意:D x 表示x位置被炸毁, R表示修复最近被炸毁的点,Q x 表示查询包括x点在内连续最大的区间并且满足这段中都是没有被炸毁。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 50000+10
#define lson left, mid, rt<<1
#define rson mid + 1, right, rt<<1|1

int tree[maxn<<2];
int l_max[maxn<<2], r_max[maxn<<2];

void build(int left, int right, int rt)
{
	tree[rt] = l_max[rt] = r_max[rt] = right-left+1;
	if(left == right) return;
	int mid = (left + right)>>1;
	build(left, mid, rt<<1);
	build(mid + 1, right, (rt<<1)|1);
}
void pushUp(int rt, int m)
{
	l_max[rt] = l_max[rt<<1];
	r_max[rt] = r_max[(rt<<1)|1];
	if(l_max[rt] == m-(m>>1)) 
		l_max[rt] += l_max[(rt<<1)|1];
	if(r_max[rt] == (m>>1))
		r_max[rt] += r_max[rt<<1];
	tree[rt] = max(tree[rt<<1], tree[(rt<<1)|1]);
	tree[rt] = max(tree[rt], r_max[rt<<1] + l_max[(rt<<1)|1] - 1);
}
void upDate(int pos, int change, int left, int right, int rt)
{
	if(left == right){
		tree[rt] = l_max[rt] = r_max[rt] = change? 1:0;
		return ;
	}
	int mid = (left + right)>>1;
	if(pos <= mid) 
		upDate(pos, change, left, mid, rt<<1);
	else if(pos > mid) 
		upDate(pos, change, mid + 1, right, (rt<<1)|1);
	pushUp(rt, right-left+1);
 } 
 int query(int pos, int left, int right, int rt)
 {
 	if(left == right || (tree[rt] == 0) || (tree[rt] == right-left+1)){
 		return tree[rt];
	 }
 	int mid = (left + right)>>1;
 	if(pos <= mid){		
 		if(pos >= mid- r_max[rt<<1] + 1){
 			return r_max[rt<<1] + l_max[(rt<<1)|1];
		 }
		else return query(pos, left, mid, rt<<1);
	 }
	 else if(pos > mid){	
	 	if(pos <= l_max[(rt<<1)|1] + mid){
	 		return r_max[rt<<1] + l_max[(rt<<1)|1];
		 }
		 else return query(pos, mid + 1, right, (rt<<1)|1);
	 }
 }
int main()
{
	int n, m, p; char op;
	while(~scanf("%d%d", &n, &m)){
		int ss[maxn], cnt = 0;
		build(1, n, 1);
		for(int i = 0; i < m; i++){
			getchar();
			scanf("%c", &op);
			if(op == 'D'){
				scanf("%d", &p); 
				ss[cnt++] = p;
				upDate(p, 0, 1, n, 1);
			}
			else if(op == 'Q'){
				scanf("%d", &p);
				int res = query(p, 1, n, 1);
				printf("%d\n", res);
			}
			else if(op == 'R'){
				if(cnt > 0){
					p = ss[--cnt];
					upDate(p, 1, 1, n, 1);
				}
			} 
		}
	}
	return 0;
 } 
 /*
20 100
D 8
D 12
Q 10
 */
 


猜你喜欢

转载自blog.csdn.net/qq_35930475/article/details/80397549
今日推荐