hdu 1540 Tunnel Warfare(Treap)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540

思路:三种操作:

D摧毁一个点

R重建最晚被修改的那个点

Q询问点x联通的点有多少个

逆向思维,D操作可以看成在平衡树上建个点,R看成在平衡树上删除一个点,Q询问x联通点个数,我们就可以直接在平衡树上找x的前驱l和后继r,点的个数就是r - l - 1,特判下当x点也被摧毁了,那么联通点数量为0。

 

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ls t[x].ch[0]
#define rs t[x].ch[1]
const int M = 6e5 + 10;
const int inf = 0x3f3f3f3f;
map<int,int>mp;
int last[M],n,m,root,cnt;
struct node{
    int ch[2],cnt,siz,val,rd;
}t[M];

void up(int x){
    t[x].siz = t[ls].siz + t[rs].siz+t[x].cnt;
}

void rotate(int &x,int d){
    int son = t[x].ch[d];
    t[x].ch[d] = t[son].ch[d^1];
    t[son].ch[d^1] = x; up(x); up(x=son);
}

void Insert(int &x,int val){
    if(!x){
        x = ++cnt;
        t[x].cnt = t[x].siz = 1;
        t[x].val = val,t[x].rd = rand();
        return ;
    }
    t[x].siz ++;
    if(t[x].val == val){
        t[x].cnt++; return ;
    }
    int d = t[x].val < val; Insert(t[x].ch[d],val);
    if(t[x].rd > t[t[x].ch[d]].rd) rotate(x,d);
}

void del(int &x,int val){
    if(!x) return ;
    if(t[x].val == val){
        if(t[x].cnt > 1){
            t[x].cnt--,t[x].siz--;return ;
        }
        bool d = t[ls].rd > t[rs].rd;
        if(ls == 0||rs == 0) x = ls+rs;
        else rotate(x,d),del(x,val);
    }
    else t[x].siz--,del(t[x].ch[t[x].val<val],val);
}

int rk(int x,int val){
    if(!x) return 0;
    if(t[x].val == val) return t[ls].siz+1;
    if(t[x].val > val) return rk(ls,val);
    return rk(rs,val)+t[ls].siz+t[x].cnt;
}

int kth(int root,int k){
    int x = root;
    while(1){
        if(k <= t[ls].siz) x = ls;
        else if(k > t[ls].siz+t[x].cnt)
            k -= t[ls].siz+t[x].cnt,x = rs;
        else return t[x].val;
    }
}

int pre(int x,int val){
    if(!x) return -inf;
    if(t[x].val >= val) return pre(ls,val);
    return max(pre(rs,val),t[x].val);
}

int nex(int x,int val){
    if(!x) return inf;
    if(t[x].val <= val) return nex(rs,val);
    return min(nex(ls,val),t[x].val);
}

int main()
{
    string op;
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    while(cin>>n>>m){
        int tot = 0,l,r,x;root = 0;
        mp.clear();t[root].siz = 0;
        Insert(root,0); Insert(root,n+1);
        for(int i = 1;i <= m;i ++){
            cin>>op;
            if(op[0]=='D'){
                cin>>x;
                if(mp[x] == 0){
                Insert(root,x);
                mp[x] = 1;
                }
                last[++tot] = x;
            }
            else if(op[0] == 'R'){
                if(!tot) continue;
                del(root,last[tot]);
                mp[last[tot]] = 0;
                tot--;
            }
            else{
                cin>>x;
                l = pre(root,x);
                r = nex(root,x);
                if(mp[x] == 1) l = r;
               // cout<<l<<" "<<r<<endl;
                cout<<max(r-l-1,0)<<endl;
            }
        }
    }
}

 

posted @ 2019-04-11 17:07  冥想选手  阅读(162)  评论(0编辑  收藏  举报