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; } } } }