标签:ffffff 排序二叉树 src 问题: lin 随机 void inpu min
[BZOJ 2770]YY的Treap
题目
志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap。友爱教教父SY如砍瓜切菜般教会了YY小朋友Treap(一种平衡树,通过对每个节点随机分配一个priority,同时保证这棵平衡树关于priority是一个小根堆以保证效率)。这时候不怎么友爱的510跑了出来,他问了YY小朋友一个极不和谐的问题:怎么求Treap中两个点之间的路径长度。YY秒了之后决定把这个问题交给你来做,但只要求出树中两点的LCA。
INPUT
第一行两个整数n,m
第二行n个整数表示每个元素的key
第三行n个整数表示每个元素的priority
接下m行,每行一条命令
I A B,插入一个元素,key为A, priority为B
D A,删除一个元素,key为A
Q A B,询问key分别为A和B的LCA的key
OUTPUT
对于每个Q输出一个整数。
SAMPLE
INPUT
2 2
1 2
4 5
Q 1 2
I 3 3
OUTPUT
1
据说和他们考试T3很像?(在家集训的力量)
差点打了个$Treap$,正解是线段树
我们考虑$Treap$的性质,显然$key$满足排序二叉树性质,而$priority$满足堆性质,所以,两点间$LCA$必为$key$区间内$priority$最小值的位置
动态开个点就行了
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 inline int read(){ 6 int sum(0),f(1); 7 char ch(getchar()); 8 for(;ch<‘0‘||ch>‘9‘;ch=getchar()) 9 if(ch==‘-‘) 10 f=-1; 11 for(;ch>=‘0‘&&ch<=‘9‘;sum=sum*10+(ch^48),ch=getchar()); 12 return sum*f; 13 } 14 typedef long long L; 15 const L inf=0x7fffffffffffffffLL; 16 const L size=1000000000; 17 struct data{ 18 L key,pri; 19 data(L x=0,L y=inf):key(x),pri(y){} 20 inline bool operator<(const data &x)const{ 21 return pri<x.pri; 22 } 23 }tr[5500010]; 24 int n,m; 25 L a[100005]; 26 int rt,cnt; 27 int lch[5500010],rch[5500010]; 28 inline void pushup(int i){ 29 tr[i]=min(tr[lch[i]],tr[rch[i]]); 30 } 31 inline void update(int &x,L pos,L w,L l,L r){ 32 if(!x) 33 x=++cnt; 34 if(l==r){ 35 tr[x]=data(pos,w); 36 return; 37 } 38 L mid((l+r)>>1); 39 if(pos<=mid) 40 update(lch[x],pos,w,l,mid); 41 else 42 update(rch[x],pos,w,mid+1,r); 43 pushup(x); 44 } 45 inline data query(int i,L ll,L rr,L l,L r){ 46 if(ll==l&&r==rr) 47 return tr[i]; 48 int mid((l+r)>>1); 49 if(rr<=mid) 50 return query(lch[i],ll,rr,l,mid); 51 if(mid<ll) 52 return query(rch[i],ll,rr,mid+1,r); 53 return min(query(lch[i],ll,mid,l,mid),query(rch[i],mid+1,rr,mid+1,r)); 54 } 55 char op[2]; 56 int main(){ 57 n=read(),m=read(); 58 for(int i=1;i<=n;++i) 59 a[i]=read(); 60 for(int i=1;i<=n;++i){ 61 L x(read()); 62 update(rt,a[i],x,-size,size); 63 } 64 while(m--){ 65 scanf("%s",op); 66 if(op[0]==‘I‘){ 67 L x(read()),y(read()); 68 update(rt,x,y,-size,size); 69 } 70 if(op[0]==‘D‘){ 71 L x(read()); 72 update(rt,x,inf,-size,size); 73 } 74 if(op[0]==‘Q‘){ 75 L x(read()),y(read()); 76 if(x>y) 77 swap(x,y); 78 printf("%lld\n",query(rt,x,y,-size,size).key); 79 } 80 } 81 }
标签:ffffff 排序二叉树 src 问题: lin 随机 void inpu min
原文地址:http://www.cnblogs.com/hzoi-mafia/p/7634214.html