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;
    }
  • 相关阅读:
    CDH中flume是已经启动着了…
    CDH中,执行HIVE脚本表联查权限问题。。
    linux screen 命令详解(未验证+研究)
    004ICMP-type对应表
    003iptables 命令介绍
    002利用zabbix监控某个目录大小
    Nginx图片剪裁模块探究 http_image_filter_module
    linux增加自定义path和manpath
    TortoiseSVN中图标的含义
    Linux SVN 搭建(YUM)安装
  • 原文地址:https://www.cnblogs.com/widsom/p/8405189.html
Copyright © 2011-2022 走看看