码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 2770]YY的Treap

时间:2017-10-07 14:24:46      阅读:182      评论:0      收藏:0      [点我收藏+]

标签: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 }
View Code

 

 

[BZOJ 2770]YY的Treap

标签:ffffff   排序二叉树   src   问题:   lin   随机   void   inpu   min   

原文地址:http://www.cnblogs.com/hzoi-mafia/p/7634214.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!