题目: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;
}