Tunnel Warfare(线段树)

题目:https://vjudge.net/problem/HDU-1540
参考:https://blog.csdn.net/chudongfang2015/article/details/52133243

以题目中的例子为例(代码的意思是):

1 2 3 4 5 6 7
初始的max 0 0 0 0 0 0 0
初始的min 8 8 8 8 8 8 8
初始每个点的连续区间 7 7 7 7 7 7 7
D3后的max 0 0 3 3 3 3 3
D3后的min 3 3 3 8 8 8 8
此时每个点的连续区间 2 2 0 4 4 4 4
D6后的max 0 0 3 3 3 6 6
D6后的min 3 3 3 6 6 6 8
此时每个点的连续区间 2 2 0 2 2 0 1

然后又要我们恢复上一条损坏的路,就先进后出,用了stack。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stack>
#define lson rt<<1, l, m  //debug好久才发现……这里顺序写错了, 
#define rson rt<<1|1, m+1, r 
#define mem(a,b) memset(a,b,sizeof(a))
#define N 50010
using namespace std;
int n,t,op[2];
stack<int> des; 
int tree1[N<<2],tree2[N<<2];//tree1是左边摧毁的最大值,tree2是右边的最小值 

void build(int rt, int l, int r){ 
	if(l==r){
		tree1[rt]=0;
		tree2[rt]=n+1;
		return; 
	}
	int m= l+r >> 1;
	build(lson);
	build(rson);
	tree1[rt]=max(tree1[rt<<1],tree1[rt<<1|1]);
	tree2[rt]=min(tree2[rt<<1],tree2[rt<<1|1]);
}

void update_max(int p, int x, int rt ,int l ,int r) {
	if(l == r) {
		tree1[rt]=x;
		return ;
	}
	int m = l+r >> 1;
	if(p<=m) update_max(p, x, lson);
	else update_max(p, x, rson);
	tree1[rt]=max(tree1[rt<<1],tree1[rt<<1|1]);
}

void update_min(int p, int x, int rt ,int l ,int r) {
	if(l == r) {
		tree2[rt]=x;
		return ;
	}
	int m = l+r >> 1;
	if(p<=m) update_min(p, x, lson);
	else update_min(p, x, rson);
	tree2[rt]=min(tree2[rt<<1],tree2[rt<<1|1]);
}

int query_max(int L, int R, int rt, int l, int r) {
	if(L<=l && r<=R){
		return tree1[rt];
	}
	int m = l+r >>1;
	int ans=0;
	if(L <= m) ans=max(ans,query_max(L,R,lson));
	if(R > m) ans=max(ans,query_max(L,R,rson));
	return ans;
}

int query_min(int L, int R, int rt, int l, int r) {
	if(L<=l && r<=R){
		return tree2[rt];
	}
	int m = l+r >>1;
	int ans=0x3f3f3f;
	if(L <= m) ans=min(ans,query_min(L,R,lson));
	if(R > m) ans=min(ans,query_min(L,R,rson));
	return ans;
}

int main() {
	while(scanf("%d%d",&n,&t)!=EOF) {
		while(!des.empty()) //清空
			des.pop();
		build(1,1,n);//初始
		for(int i=0;i<t;i++){
			scanf("%s",op);
			if(op[0]=='D'){
				int a;
				scanf("%d",&a);
				des.push(a);//把损坏的路加入stack
				update_min(a,a,1,1,n);//更新大小
				update_max(a,a,1,1,n);
			}
			else if(op[0]=='Q'){
				int a,b,c;
				scanf("%d",&a);
				b=query_max(1,a,1,1,n);
				c=query_min(a,n,1,1,n);
				if(b==c) 
					printf("%d\n",0);
				else 
					printf("%d\n",c-b-1);
			}
			else{
				int a=des.top();//拿出上一条损坏的路
				update_min(a,n+1,1,1,n);
				update_max(a,0,1,1,n);
				des.pop();//把这条路去掉
			} 
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43326028/article/details/86673364