【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——线段树分治
首先感谢题解小哥,他在标算外又总结了三种做法. 此处仅提及最后一种做法. 首先考虑题目中要求的所有结点度数为奇数的限制. 对于每一个联通块,因为所有结点总度数是偶数,所以总结点数也必须是偶数的.即所有 ...
随机推荐
- redis学习笔记——应用场景
最近在看redis入门指南,现在就自己的学习情况说说自己的理解. 字符串类型(String) 字符串类型是Redis中最基本的类型,能存储任意形式的字符串,包括二进制数据.如一张照片也可以用字符串类型 ...
- Ios 调用Appstore 下载界面 [[UIApplication sharedApplication] openURL
http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?mt=8&id=286274367 id = itunesconn ...
- 【Python3 爬虫】14_爬取淘宝上的手机图片
现在我们想要使用爬虫爬取淘宝上的手机图片,那么该如何爬取呢?该做些什么准备工作呢? 首先,我们需要分析网页,先看看网页有哪些规律 打开淘宝网站http://www.taobao.com/ 我们可以看到 ...
- Linux下配置两个或多个Tomcat启动
Linux下配置两个或多个Tomcat启动 (2012-08-14 11:59:31) 转载▼ 标签: 杂谈 分类: linux_tomcat 步骤如下: (1)修改/etc/profile文件.添加 ...
- java之super关键字
super关键字: 在java中使用super来引用基类的成分. 程序code: class FatherClass{ public int value; public void f(){ value ...
- js获取本页的来源地址
document.referrer 该属性可以获取到文档的载入地址 需要注意必须是通过改变localtion的href属性或a标签跳转才能获取到 否者将获取到空字符串
- Flex Air应用程序更改任务栏图标
Air应用程序中相关图标更改的方法: 1.安装后的应用程序图标和运行时的任务栏图标 这两个是一起的,通过更改配置文件application.xml中的icon节点,分别针对不同大小进行设置,未设置的会 ...
- poj 3666 河南省第七届程序设计D题(山区修路)
题目大意: 给定一个序列,以最小代价将其变成单调不增或单调不减序列,求最小的变动价值:需要用到离散化dp 状态转移方程: dp[i][j]=abs(j-w[i])+min(dp[i-1][k]);(k ...
- 如何给unity3d工程加入依赖的android工程
最近在忙着接平台的事,需要接入各种各样的android平台sdk来发布.在接sdk的时候遇到了这样的一个情况,有点麻烦,所以纪录一下. 有些sdk的接入是提供jar包,这样的可以简单地将jar包制作成 ...
- Unity3D - 发布Android游戏
本文将介绍如何使用Unity3D来发布Android游戏,这里我使用的Unity3D版本为4.6.3f1 下载Java SDK 使用Unity3D来发布Android游戏时需要用到Android SD ...