hdu1540

hdu1540 Tunnel Warfare
传送门
题意
(n(nleq 50000))个点连成一条线,进行(m)次操作,操作共有三种:
1.毁掉一个点
2.查询与某点连续的点的数量
3.重建上一个被毁掉的点
计算每次查询操作的值
题解
线段树区间合并
每个元素内设三个变量:从区间左端点开始的最长连续点的个数(lmx),从区间右端点开始的最长连续点的个数(rmx),区间内最长连续点的个数(amx)
更新操作直接更新到对应点,之后向上合并
查询操作查询区间内包含某个点的连续的点的个数。如果当前点在左区间的(rmx)之内,则需要加上右区间的(lmx)。同理,如果当前点在右区间的(lmx)之内,则需要加上左区间的(rmx)

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;

const int maxn=50010;
int n,m;
char s[5];
stack<int> stk;
struct node{
    int lmx,rmx,amx;
}tree[4*maxn];

void pushup(int o,int l,int r){
    int mid=(l+r)>>1;
    tree[o].lmx=tree[o<<1].lmx;
    if(tree[o<<1].lmx==mid-l+1) tree[o].lmx+=tree[o<<1|1].lmx;
    tree[o].rmx=tree[o<<1|1].rmx;
    if(tree[o<<1|1].rmx==r-mid) tree[o].rmx+=tree[o<<1].rmx;
    tree[o].amx=max(max(tree[o<<1].amx,tree[o<<1|1].amx),tree[o<<1].rmx+tree[o<<1|1].lmx);
}

void build(int o,int l,int r){
    if(l==r){
        tree[o].lmx=tree[o].rmx=tree[o].amx=1;
        return;
    }
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    pushup(o,l,r);
}

void change(int o,int l,int r,int x,int v){
    if(l==r){
        tree[o].lmx=tree[o].rmx=tree[o].amx=v;
        return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) change(o<<1,l,mid,x,v);
    else change(o<<1|1,mid+1,r,x,v);
    pushup(o,l,r);
}

int query(int o,int l,int r,int x){
    if(l==r || tree[o].amx==0 || tree[o].amx==r-l+1) return tree[o].amx;
    int mid=(l+r)>>1;
    int ans;
    if(x<=mid){
        if(x>=mid-tree[o<<1].rmx+1) ans=query(o<<1,l,mid,x)+query(o<<1|1,mid+1,r,mid+1);
        else ans=query(o<<1,l,mid,x);
    }
    else{
        if(x<=mid+tree[o<<1|1].lmx) ans=query(o<<1|1,mid+1,r,x)+query(o<<1,l,mid,mid);
        else ans=query(o<<1|1,mid+1,r,x);
    }
    return ans;
}

int main(){
    while(~scanf("%d %d",&n,&m)){
        build(1,1,n);
        while(!stk.empty()) stk.pop();
        while(m--){
            scanf("%s",s);
            if(s[0]=='D'){
                int x;
                scanf("%d",&x);
                change(1,1,n,x,0);
                stk.push(x);
            }
            else if(s[0]=='Q'){
                int x;
                scanf("%d",&x);
                printf("%d
",query(1,1,n,x));
            }
            else{
                int x;
                x=stk.top();
                stk.pop();
                change(1,1,n,x,1);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fxq1304/p/13567856.html