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

    HDU 1540

    思路1:

    树状数组+二分

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define ls rt<<1,l,m
    #define rs rt<<1|1,m+1,r
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=5e4+5;
    int bit[N];
    bool vis[N];
    int n;
    int add(int x,int a){
        while(x<=n)bit[x]+=a,x+=x&-x;
    }
    int query(int x){
        int ans=0;
        while(x)ans+=bit[x],x-=x&-x;
        return ans;
    }
    bool check(int x,int m){
        //cout<<query(m)<<' '<<query(x-1)<<endl;
        if(query(m)-query(x-1)<m-x+1)return true;
        else return false;
    }
    bool check1(int x,int m){
        if(query(x)-query(m-1)<x-m+1)return true;
        else return false;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        int m,x;
        char c;
        while(cin>>n>>m)
        {
            mem(bit,0);
            mem(vis,false);
            for(int i=1;i<=n;i++)add(i,1);
            stack<int>s;
            for(int i=1;i<=m;i++){
                cin>>c;
                if(c=='D'){
                    cin>>x;
                    if(!vis[x])add(x,-1),vis[x]=true;
                    s.push(x);
                }
                else if(c=='Q'){
                    cin>>x;
                    int l=x,r=n,mid=(l+r)>>1;
                    while(l<r){
                        //cout<<l<<' '<<r<<' '<<query(mid)<<' '<<query(x-1)<<endl;
                        if(check(x,mid))r=mid-1;
                        else l=mid;
                        mid=(l+r+1)>>1;
    
    
                    }
                    int R=mid;
                    l=1,r=x,mid=(l+r)>>1;
                    while(l<r){
                        if(check1(x,mid))l=mid+1;
                        else r=mid;
                        mid=(l+r)>>1;
                    }
                    int L=mid;
                    if(vis[x])cout<<0<<endl;
                    else cout<<R-L+1<<endl;
                }
                else{
                    if(vis[s.top()])add(s.top(),1),vis[s.top()]=false;
                    s.pop();
                }
            }
        }
        return 0;
    }

    思路2:

    线段树区间合并

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define ls rt<<1,l,m
    #define rs rt<<1|1,m+1,r
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=5e4+5;
    struct tree{
        int ll,rr,len;//ll表示以当前区间左端点为左端点最长连续区间的长度,rr表示以当前区间右端点为右端点最长连续区间的长度,len表示当前区间的长度
    }tree[N<<2];
    void push_up(int rt){
        if(tree[rt<<1].ll==tree[rt<<1].len)tree[rt].ll=tree[rt<<1].ll+tree[rt<<1|1].ll;
        else tree[rt].ll=tree[rt<<1].ll;
        if(tree[rt<<1|1].rr==tree[rt<<1|1].len)tree[rt].rr=tree[rt<<1|1].rr+tree[rt<<1].rr;
        else tree[rt].rr=tree[rt<<1|1].rr;
    }
    void build(int rt,int l,int r){
        tree[rt].ll=tree[rt].rr=tree[rt].len=r-l+1;
        if(l==r)return ;
        int m=(l+r)>>1;
        build(ls);
        build(rs);
    }
    void update(int p,int v,int rt,int l,int r){
        if(l==r){
            tree[rt].ll=tree[rt].rr=v;
            return ;
        }
        int m=(l+r)>>1;
        if(p<=m)update(p,v,ls);
        else update(p,v,rs);
        push_up(rt);
    }
    int query(int p,int rt,int l,int r){
        if(rt==1){
            if(l+tree[rt].ll-1>=p)return tree[rt].ll;
            if(r-tree[rt].rr+1<=p)return tree[rt].rr;
        }
        else{
            if(l+tree[rt].ll-1>=p)return tree[rt].ll+tree[rt-1].rr;
            if(r-tree[rt].rr+1<=p)return tree[rt].rr+tree[rt+1].ll;
        }
        if(l==r)return 0;
        int m=(l+r)>>1;
        if(p<=m)return query(p,ls);
        else return query(p,rs);
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,m,x;
        char c;
        while(cin>>n>>m){
            stack<int>s;
            build(1,1,n);
            while(m--){
                cin>>c;
                if(c=='D'){
                    cin>>x;
                    s.push(x);
                    update(x,0,1,1,n);
                }
                else if(c=='Q'){
                    cin>>x;
                    cout<<query(x,1,1,n)<<endl;
                }
                else{
                    x=s.top();
                    s.pop();
                    update(x,1,1,1,n);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    开源测试工具 JMeter 介绍 物联网大并发测试实战 01
    使用测试客户端「玩转」MQTT 5.0
    写给PPT用,可测试性驱动开发导向IOC的过程
    .net并行库的一些记录
    windows上python和django开发环境的安装和配置
    MongoDB的Journaling的工作原理(每日一译)
    留给晚上分享用的python代码
    为什么我们需要可测试的面向对象开发(翻译 )
    使用谷歌统计来跟踪网页加载时间
    酷壳上的一道面试题
  • 原文地址:https://www.cnblogs.com/widsom/p/8405189.html
Copyright © 2011-2022 走看看