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;
}
原文地址:https://www.cnblogs.com/widsom/p/8405189.html