• 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;
    }
    
  • 相关阅读:
    在三台服务器上使用docker搭建集群
    杂项
    dockercompose部署emqx、minio、redis、nacos、kafka集群(在一台虚拟机上)
    Hello
    为什么不建议你在 Docker 中跑 MySQL?
    CPU飙升!故障分析解决过程详解
    使用Vue的插件clipboard使用复制功能
    如何杀死task
    正则表达式验证数字
    ES6学习小结
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13567856.html
Copyright © 2020-2023  润新知