zoukankan      html  css  js  c++  java
  • Tunnel Warfare HDU

    题意: 在一条直线上右连续的n个点,现在,给你m个操作,D  x   破坏点 x。Q   x 查询,点x所在的区间的最长的没被破坏的连续的点的个数。

    思路:线段数的区间更新 ,节点维护区间的最长连续的点的个数,其中有两个难点,即PushUp函数,和 query(查询) 函数

    具体操作即作用在注释里面都有写到。(不明白的可以评论,或者私我,有时间一定马上回复,谢谢支持!)

    (query操作参考了kuangbindalao的博客,注释加上了一点我自己的理解,如有错误,欢迎指出)

    #include "iostream"
    #include "stack"
    #include "algorithm"
    using  namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const  int Max=50005;
    int sum[Max<<2],lsum[Max<<2],rsum[Max<<2];//分别记录总区间,从左端点开始,从右端点开始的最长连续区间
    void build(int l,int r,int rt)
    {
        sum[rt]=lsum[rt]=rsum[rt]=r-l+1;//最初,区间的最长连续区间即本区间的长度
        if(l==r) return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void PushUp(int rt,int ll,int lr)
    {
        lsum[rt]=lsum[rt<<1];
        rsum[rt]=rsum[rt<<1|1];
        if(lsum[rt]==ll) lsum[rt]+=lsum[rt<<1|1];//如果左区间的最长连续区间与左区间等长,说明区间没有被隔开,那么总区间的
        if(rsum[rt]==lr) rsum[rt]+=rsum[rt<<1];//区间还要加上右区间的最长连续区间,对于右区间的来说也是如此
        sum[rt]=max(rsum[rt<<1]+lsum[rt<<1|1],max(sum[rt<<1],sum[rt<<1|1]));//最后,总区间的最长连续区间即为可能的三个区间的最大值
    }
    void update(int c,int x,int l,int r,int rt)
    {
        if(l==r){
            sum[rt]=lsum[rt]=rsum[rt]=c?1:0;//单点更新,如果是删除操作,那么赋值为0,否则为1
            return;
        }
        int m=(l+r)>>1;
        if(x<=m) update(c,x,lson);
        else update(c,x,rson);
        PushUp(rt,m-l+1,r-m);//更新值
    }
    int query(int x,int l,int r,int rt)
    {
        if(l==r||sum[rt]==0||sum[rt]==r-l+1)//如果已经到了叶子节点或者最长连续区间为0或者最长连续区间为区间的长都可以直接返回
            return sum[rt];
        int m=(l+r)>>1;
        if(x<=m){
            if(x>=m-rsum[rt<<1]+1)//因为t<=mid,看左子树,m-rsum[rt<<1]+1代表左子树右边连续区间的左边界值,如果t在左子树的右区间内
            return query(x,lson)+query(m+1,rson);//那么还要加上右边的一段区间
            else//如果不在左子树的右边界区间内,则只需要看左子树
                return query(x,lson);
        }
        else{
            if(x<=m+1+lsum[rt<<1|1]-1)//右子树同理
                return query(x,rson)+query(m,lson);
            else
                return query(x,rson);
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        int n,m;
        while(cin>>n>>m){
            stack<int> s;//用一个栈来记录删除的点
            if(!s.empty()) s.pop();
            build(1,n,1);
            char ch;
            int x;
            while(m--){
                cin>>ch;
                if(ch=='D'){
                    cin>>x;
                    s.push(x);
                    update(0,x,1,n,1);
                }
                else if(ch=='R'){
                    if(x>0){
                        x=s.top();
                        s.pop();
                        update(1,x,1,n,1);
                    }
                }
                else{
                    cin>>x;
                    cout<<query(x,1,n,1)<<endl;
                }
            }
        }
        return  0;
    }

  • 相关阅读:
    当最好的朋友背叛你的时候
    那就这样沉沦??
    Struts初步知识JSP实例学习教程
    结合struts和hibernate谈J2EE架构的数据表示
    创建 Controller
    对话:关于架构、设计与需求
    Struts 应用转移到 Struts 2 一
    Struts 应用转移到 Struts 2 二
    出现空白网页可能的原因
    jsp常用功能模块JSP实例学习教程
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9092858.html
Copyright © 2011-2022 走看看