【BZOJ2770】YY的Treap 结论+线段树
【BZOJ2770】YY的Treap
Description
志向远大的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
1 2
4 5
Q 1 2
I 3 3
Sample Output
HINT
数据保证n<=10^5,m<=3*10^5
其余整数均不超过long的范围
数据保证任意时刻树中key和priority均不相同
题解:上来的第一直觉就是猜结论:Treap中a和b的LCA就是key值在a,b之间的,priority最小的点。一开始还想了想怎么证,后来发现这么显然的结论还用证~
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson x<<1
#define rson x<<1|1
using namespace std;
typedef long long ll;
const int maxn=400010;
int n,m,nm,tot;
int s[maxn<<2];
int op[maxn],pa[maxn];
ll pr[maxn],pb[maxn],ref[maxn],v[maxn];
char str[10];
struct node
{
ll val;
int org;
}p[maxn<<1];
inline int MN(int a,int b)
{
return v[a]<v[b]?a:b;
}
bool cmp(const node &a,const node &b)
{
return a.val<b.val;
}
void build(int l,int r,int x)
{
if(l==r)
{
s[x]=l;
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
s[x]=MN(s[lson],s[rson]);
}
void updata(int l,int r,int x,int y)
{
if(l==r) return ;
int mid=(l+r)>>1;
if(y<=mid) updata(l,mid,lson,y);
else updata(mid+1,r,rson,y);
s[x]=MN(s[lson],s[rson]);
}
int query(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b) return s[x];
int mid=(l+r)>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return MN(query(l,mid,lson,a,b),query(mid+1,r,rson,a,b));
}
inline ll rd()
{
ll ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i;
for(i=1;i<=n;i++) p[++tot].val=rd(),p[tot].org=i;
for(i=1;i<=n;i++) pr[i]=rd();
for(i=1;i<=m;i++)
{
scanf("%s",str);
if(str[0]=='I') op[i]=0,p[++tot].val=rd(),p[tot].org=i+n,pb[i]=rd();
if(str[0]=='D') op[i]=1,p[++tot].val=rd(),p[tot].org=i+n;
if(str[0]=='Q') op[i]=2,p[++tot].val=rd(),p[tot].org=i+n,p[++tot].val=rd(),p[tot].org=i+n;
}
sort(p+1,p+tot+1,cmp);
ref[0]=-1ll<<60;
for(i=1;i<=tot;i++)
{
if(p[i].val>ref[nm]) ref[++nm]=p[i].val,v[nm]=1ll<<60;
if(p[i].org<=n) v[nm]=pr[p[i].org];
else
{
p[i].org-=n;
if(op[p[i].org]==0) pa[p[i].org]=nm;
if(op[p[i].org]==1) pa[p[i].org]=nm;
if(op[p[i].org]==2)
{
if(!pa[p[i].org]) pa[p[i].org]=nm;
else pb[p[i].org]=nm;
}
}
}
build(1,nm,1);
for(i=1;i<=m;i++)
{
if(op[i]==0) v[pa[i]]=pb[i],updata(1,nm,1,pa[i]);
if(op[i]==1) v[pa[i]]=1ll<<60,updata(1,nm,1,pa[i]);
if(op[i]==2) printf("%lld\n",ref[query(1,nm,1,pa[i],pb[i])]);
}
return 0;
}
【BZOJ2770】YY的Treap 结论+线段树的更多相关文章
- BZOJ1901 ZOJ2112 线段树+treap (线段树套线段树)
BZOJ1901: 线段树套线段树做法: (外层线段树 里层动态开节点的权值线段树) 有一个小小的trick 可以省掉二分变成nlog^2n的 就是把查询的区间都取出来- logn个一起走- 2016 ...
- [HNOI2018]转盘[结论+线段树]
题意 题目链接 分析 首先要发现一个结论:最优决策一定存在一种 先在出发点停留之后走一圈 的情况,可以考虑如下证明: 如果要停留的话一定在出发点停留,这样后面的位置更容易取到. 走超过两圈的情况都可以 ...
- [BJOI2019] 删数 [dp转贪心结论+线段树]
题面 传送门 思路 dp部分 以下称合法序列为原题面中可以删空的序列 这个是我在模拟考场上的思路 一开始我是觉得,这个首先可以写成一个dp的形式:$dp[i][j]$表示用$j$个数字填满了目标序列的 ...
- BZOJ2770: YY的Treap
原本看标题还以为是treap的题,但是实际上是线段树. 求两点的LCA相当于求区间priority最小值的位置. 然后就可以离线先离散化然后建树做了. 记录的minpos是线段树上叶子结点的节点编号. ...
- BZOJ3173 TJOI2013最长上升子序列(Treap+ZKW线段树)
传送门 Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input ...
- UNR#3 Day1——[ 堆+ST表+复杂度分析 ][ 结论 ][ 线段树合并 ]
地址:http://uoj.ac/contest/45 第一题是鸽子固定器. 只会10分.按 s 从小到大排序,然后 dp[ i ][ j ][ k ] 表示前 i 个元素.已经选了 j 个.最小值所 ...
- 非旋treap套线段树
BZOJ3065. 去年用pascal 块链过了.. 今年来试了试非旋treap大法 注定被块链完爆 代码留这. 第一份 :辣鸡的 垃圾回收做法 跑得极慢 #include <bits/ ...
- BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】
BZOJ3196 Tyvj1730 二逼平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名 ...
- 【做题】cf603E——线段树分治
首先感谢题解小哥,他在标算外又总结了三种做法. 此处仅提及最后一种做法. 首先考虑题目中要求的所有结点度数为奇数的限制. 对于每一个联通块,因为所有结点总度数是偶数,所以总结点数也必须是偶数的.即所有 ...
随机推荐
- javaEE开发之文件下载
package com.example.web; import java.io.File; import java.io.FileInputStream; import java.io.IOExcep ...
- 基于php的银行卡实名认证接口调用代码实例
银行卡二元素检测,检测输入的姓名.银行卡号是否一致. 银行卡实名认证接口:https://www.juhe.cn/docs/api/id/188 <?php // +-------------- ...
- ubuntu cp(copy) command
e.g. #cp –p –R /opt/lampp/drv ~/test Ubuntu_Linux命令:cp(copy)复制文件或目录 功能: 复制文件或目录 www.2cto.com 说 ...
- How to get the url of a page in OpenERP?
How to get the url of a page in OpenERP? User is using OpenERP. I have a button on one web page. The ...
- jQuery 文档操作 - insertAfter() ,insertBefore(),after(),before() 方法
这个方法跟prependTo()和appendTo()不一样的地方在于,一个是仍然插入到元素内部,而insertAfter和insertBefore是插入到元素外部. 这里拿insertBefore来 ...
- popupwindow从底部弹出
参考了网上的一些代码,自己写了个类,上代码 /** * Created by Lee on 2016/2/26. */ public class CameraPopupWindow { private ...
- Android应用TranslateAnimation移动之后,利用视图的setLayoutPara
Android中利用TranslateAnimation移动时,不设置mTranslateAnimation.setFillAfter(true);,而利用视图的setLayoutParams来重新定 ...
- webpack 打包压缩 ES6文件报错UglifyJs + Unexpected token punc ((); 或者 Unexpected token: operator (>)
webpack 打包压缩 ES6文件报错UglifyJs + Unexpected token punc ((); 或者 Unexpected token: operator (>) 解决方案 ...
- Atitit.一些公司的开源项目 重大知名开源项目attilax总结
Atitit.一些公司的开源项目 重大知名开源项目attilax总结 1. Twitter--Bootstrap:1 2. Google2 2.1. Gson2 2.2. Angular.Js2 2. ...
- Atitit.uml2 api 的编程代码实现设计uml开发 使用eclipse jar java 版本
Atitit.uml2 api 的编程代码实现设计uml开发 使用eclipse jar java 版本 1. clipse提供了UML的底层Java包, 1 2. MDTUML2Getting St ...