zoukankan      html  css  js  c++  java
  • [线段树] (i) hdu1540 (区间合并)

    hdu 1540  Tunnel Warfare

    如在阅读本文时遇到不懂的部分,请在评论区询问,或跳转 线段树总介绍

    推荐先阅读 (线段树) (h) poj3667 (区间合并) 以获得线段树区间合并的一些知识

    本题与上题(poj3667)基本相同,但要注意询问部分要求的是包含x的0区间长度

    query (看看代码,倒也直观,很容易理解)

    int query(int rt,int l,int r,int x){
        if(l==r||!MaxiLen[rt]||MaxiLen[rt]==r-l+1)return MaxiLen[rt];
        //找到x ||含x的区间全是0 || 含x的区间全是1
      //自己看看分别会返回什么...MaxiLen维护区间内最长的0
    int mid=l+r>>1; if(x<=mid){ if(x>=mid-last[LS]+1)return last[LS]+pre[RS]; //夹中间 else return query(LS,l,mid,x); //LS }else{ if(x<=mid+pre[RS])return last[LS]+pre[RS]; //夹中间 else return query(RS,mid+1,r,x); //RS } }

    左右去找x十分普通,重点是夹在中间的情况,要分左右区间的前驱后继来看;以及整个区间的特殊情况判定 if(l==r||!MaxiLen[rt]||MaxiLen[rt]==r-l+1) 这三种可以合并起来写

    代码

    /*i.hdu1540*/
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    using namespace std;
    const int N=2e6+3;
    int STK[N],HEAD=0;int n,m;
    int pre[N<<2],last[N<<2],MaxiLen[N<<2];
    #define LS (rt<<1)
    #define RS (LS|1)
    
    void build(int rt,int l,int r){
        pre[rt]=last[rt]=MaxiLen[rt]=r-l+1;
        if(l==r)return;
        int mid=l+r>>1;
        build(LS,l,mid);
        build(RS,mid+1,r);
    }
    void pushup(int rt,int l,int r){
        MaxiLen[rt]=max(max(MaxiLen[LS],MaxiLen[RS]),pre[RS]+last[LS]);
        int mid=l+r>>1;
        if(pre[LS]==mid-l+1)pre[rt]=mid-l+1+pre[RS];
        else pre[rt]=pre[LS];
        if(last[RS]==r-mid)last[rt]=r-mid+last[LS];
        else last[rt]=last[RS];
        return;
    }
    void update(int rt,int l,int r,int x,int p){
        if(l==r){pre[rt]=last[rt]=MaxiLen[rt]=p;return;}
        int mid=l+r>>1;
        if(x<=mid)update(LS,l,mid,x,p);
        else update(RS,mid+1,r,x,p);
        pushup(rt,l,r);
    }
    int query(int rt,int l,int r,int x){
        if(l==r||!MaxiLen[rt]||MaxiLen[rt]==r-l+1)return MaxiLen[rt];
        //找到x ||含x的区间全是0 || 含x的区间全是1
        int mid=l+r>>1;
        if(x<=mid){
            if(x>=mid-last[LS]+1)return last[LS]+pre[RS]; //夹中间
            else return query(LS,l,mid,x);                 //LS
        }else{
            if(x<=mid+pre[RS])return last[LS]+pre[RS];     //夹中间
            else return query(RS,mid+1,r,x);               //RS
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF){
            build(1,1,n);
            char c=getchar();int x;
            while(m--){
                c=getchar();
                if(c=='D'){
                    scanf("%d",&x);
                    update(1,1,n,x,0);
                    STK[++HEAD]=x;
                }
                else if(c=='Q'){
                    scanf("%d",&x);
                    printf("%d
    ",query(1,1,n,x));
                }
                else update(1,1,n,STK[HEAD--],1);
                c=getchar();
            }
        }
        return 0;
    }
  • 相关阅读:
    将包含<pre>标签的json转换成js
    JS 获取系统时间
    JS 对url进行编码
    DevExpress.XtraCharts.ChartControl 实例
    VB 窗体继承
    datagrid 属性
    SQLite操作总结
    Struts2 简介及学习方法介绍
    struts2 中使用DMI(动态调用方法)方式配置action
    JSP 里 的 basePath
  • 原文地址:https://www.cnblogs.com/lsy263/p/11229113.html
Copyright © 2011-2022 走看看