Tunnel Warfare HDU

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f; 
const int N=50000+10;
struct node{
    int l,r;
    int maxx;
    int minn;
} tr[N*4];
//保存历史记录,被毁的 
int history[N*4];
int n,m;
void build(int i,int l,int r)
{
    tr[i].l=l;
    tr[i].r=r;
    if(l==r)
    {
        //初始化 
        //i到n的最小
        tr[i].minn=n+1;
        //1到i的最大
        tr[i].maxx=0;
        return;
    }
    int mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    tr[i].maxx=max(tr[i*2].maxx,tr[i*2+1].maxx);
    tr[i].minn=min(tr[i*2].minn,tr[i*2+1].minn);
}
//更新最小值
void updateMin(int i,int id,int val)
{
    if(tr[i].l==tr[i].r)
    {
        tr[i].minn=val;
        return;
    }
    int mid=tr[i].l+tr[i].r>>1;
    if(id<=mid)
        updateMin(i*2,id,val);
    else
        updateMin(i*2+1,id,val);
 
    tr[i].minn=min(tr[i*2].minn,tr[i*2+1].minn);
}
//更新最大值
void updateMax(int i,int id,int val)
{
    if(tr[i].l==tr[i].r)
    {
        tr[i].maxx=val;
        return;
    }
    int mid=(tr[i].l+tr[i].r)/2;
    if(id<=mid)
        updateMax(i*2,id,val);
    else
        updateMax(i*2+1,id,val);
 
    tr[i].maxx=max(tr[i*2].maxx,tr[i*2+1].maxx);
}
//查询最小值
int queryMin(int i,int ql,int qr)
{
    //当前区间在目标区间内
    if(ql<=tr[i].l&&qr>=tr[i].r)
        return tr[i].minn;
    int mid=(tr[i].l+tr[i].r)/2;
    int res=INF;
    if(ql<=mid)
        res=min(res,queryMin(i*2,ql,qr));
    if(qr>mid)
        res=min(res,queryMin(i*2+1,ql,qr));
    return res;
}
//查询最大值
int queryMax(int i,int ql,int qr)
{
    //当前区间在目标区间内
    if(ql<=tr[i].l&&qr>=tr[i].r)
        return tr[i].maxx;
    int mid=(tr[i].l+tr[i].r)/2;
    int res=0;
    if(ql<=mid)
        res=max(res,queryMax(i*2,ql,qr));
    if(qr>mid)
        res=max(res,queryMax(i*2+1,ql,qr));
    return res;
}
int main()
{
 
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        build(1,1,n);
        int cnt=0;
        memset(history,0,sizeof history );
        while(m--){
            char str[5];
            scanf("%s",str);
            //破坏 
            if(str[0]=='D')
            {
                int x;
                scanf("%d",&x);
                //把x对应的值更新成x
                
                //初始化时,默认1到x最大到结尾
                //x到n最小到开头0
                 
                //现在更新为自己, 
                
                //如果查询的区间包括x,最大最小都会返回x或者其他被毁的 
                updateMax(1,x,x);
                updateMin(1,x,x);
                //记录被毁的 
                history[++cnt]=x;
            }
            //查询 
            else if(str[0]=='Q')
            {
                int x;
                scanf("%d",&x);
                int maxx=queryMax(1,1,x);
                int minn=queryMin(1,x,n);
                //特判
                //如果最大最小相同,说明自身被毁 
                if(maxx==minn)
                    printf("0
");
                else
                    //从当前点往后的最小,也就是最近的被毁的
                    //从当前点往前最大的,也就是最近的被毁的
                    //做差再减去1就是长度 
                    printf("%d
",minn-maxx-1);
            }
            else
            {
                //恢复最后被毁的,将对应初始值改回
                int temp=history[cnt--];
                updateMin(1,temp,n+1);
                updateMax(1,temp,0);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12294696.html