Written with StackEdit.

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

2 2

1 2

4 5

Q 1 2

I 3 3

Sample Output

1

HINT

数据保证\(n<=10^5,m<=3*10^5\).

其余整数均不超过\(int\)的范围.

数据保证任意时刻树中\(key\)和\(priority\)均不相同.

Solution

  • 此题就是对\(treap\)基本性质的一个考察.
  • \(C\)是\(A,B\)的\(LCA\)(假设\(key_a<key_b\)).需要满足\(key_c\in [key_a,key_b]\),这样能保证\(A,B\)到根的路径上都经过\(C\).
  • 而要求最近的公共祖先,根据\(priority\)满足小根堆的性质,只需找出其中\(priority\)最小的点即为\(LCA\).
  • 可以建一颗权值线段树,问题转化为修改,删除,以及区间上查询最值.
#include<bits/stdc++.h>
#define inf 0x7fffffff
#define root Tree[o]
#define lson Tree[o<<1]
#define rson Tree[o<<1|1]
using namespace std;
typedef long long LoveLive;
typedef pair<int,int> pii;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int MAXN=4e5+10;
int n,m;
struct Query{
int op;
int a,b;//key,pro
int ans,id;
}q[MAXN];
int kc[MAXN];
struct node{
int l,r,mi,pos,sum,val;
}Tree[MAXN<<3];
void phup(int o)
{
if(lson.mi<rson.mi)
root.mi=lson.mi,root.pos=lson.pos;
else
root.mi=rson.mi,root.pos=rson.pos;
root.sum=lson.sum+rson.sum;
}
void bd(int l,int r,int o)
{
int mid=(l+r)>>1;
root.l=l,root.r=r;
root.mi=inf;
root.sum=0;
if(l==r)
return;
bd(l,mid,o<<1);
bd(mid+1,r,o<<1|1);
}
void add(int o,int x,int pos)
{
int l=root.l,r=root.r;
int mid=(l+r)>>1;
if(l==r)
{
root.val=x;
root.mi=x;
root.pos=l;
++root.sum;
return;
}
if(pos<=mid)
add(o<<1,x,pos);
else
add(o<<1|1,x,pos);
phup(o);
}
void del(int o,int pos)
{
int l=root.l,r=root.r;
int mid=(l+r)>>1;
if(l==r)
{
root.mi=inf;
--root.sum;
return;
}
if(pos<=mid)
del(o<<1,pos);
else
del(o<<1|1,pos);
phup(o);
}
void ins(int x,int pos)
{
add(1,x,pos);
}
void rem(int pos)
{
del(1,pos);
}
int ansmi,anspos;
void qy(int o,int L,int R)
{
int l=root.l,r=root.r;
int mid=(l+r)>>1;
if(r<L || l>R)
return;
if(L<=l && r<=R)
{
if(root.mi<ansmi)
ansmi=root.mi,anspos=root.pos;
return;
}
if(L<=mid)
qy(o<<1,L,R);
if(R>mid)
qy(o<<1|1,L,R);
}
int main()
{
n=read(),m=read();
int cnt=0;
for(int i=1;i<=n;++i)
{
q[i].op=1;
q[i].a=read();
kc[++cnt]=q[i].a;
q[i].id=i;
}
for(int i=1;i<=n;++i)
q[i].b=read();
int idx=n;
for(int i=1;i<=m;++i)
{
++idx;
q[idx].id=idx;
char buf[2];
scanf("%s",buf);
if(buf[0]=='I')
{
q[idx].op=1;
q[idx].a=read();
kc[++cnt]=q[idx].a;
q[idx].b=read();
}
else if(buf[0]=='D')
{
q[idx].op=2;
q[idx].a=read();
kc[++cnt]=q[idx].a;
}
else
{
q[idx].op=3;
q[idx].a=read();
kc[++cnt]=q[idx].a;
q[idx].b=read();
kc[++cnt]=q[idx].b;
}
}
bd(1,2*n,1);
sort(kc+1,kc+1+cnt);
cnt=unique(kc+1,kc+1+cnt)-(kc+1);
for(int i=1;i<=idx;++i)
{
if(q[i].op==1)
{
q[i].a=lower_bound(kc+1,kc+1+cnt,q[i].a)-kc;
ins(q[i].b,q[i].a);
}
else if(q[i].op==2)
{
q[i].a=lower_bound(kc+1,kc+1+cnt,q[i].a)-kc;
rem(q[i].a);
}
else if(q[i].op==3)
{
q[i].a=lower_bound(kc+1,kc+1+cnt,q[i].a)-kc;
q[i].b=lower_bound(kc+1,kc+1+cnt,q[i].b)-kc;
ansmi=inf;
qy(1,min(q[i].a,q[i].b),max(q[i].a,q[i].b));
printf("%d\n",kc[anspos]);
}
}
return 0;
}

bzoj 2770 YY的Treap的更多相关文章

  1. 【莫比乌斯反演】关于Mobius反演与gcd的一些关系与问题简化(bzoj 2301 Problem b&&bzoj 2820 YY的GCD&&BZOJ 3529 数表)

    首先我们来看一道题  BZOJ 2301 Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd( ...

  2. 【BZOJ2770】YY的Treap 结论+线段树

    [BZOJ2770]YY的Treap Description 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了Y ...

  3. 【bzoj2770】YY的Treap 权值线段树

    题目描述 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了YY小朋友Treap(一种平衡树,通过对每个节点随机分 ...

  4. [BZOJ 2820] YY的gcd(莫比乌斯反演+数论分块)

    [BZOJ 2820] YY的gcd(莫比乌斯反演+数论分块) 题面 给定N, M,求\(1\leq x\leq N, 1\leq y\leq M\)且gcd(x, y)为质数的(x, y)有多少对. ...

  5. bzoj 2820 YY的GCD - 莫比乌斯反演 - 线性筛

    Description 神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对kAc这种 傻×必 ...

  6. bzoj 2770 堆的中序遍历性质

    我们知道二叉搜索树的中序遍历是一个已经排好序的序列,知道序列我们无法确定树的形态(因为有多种). 但是,Treap如果告诉我们它的关键字以及权值,那么就可以唯一确定树的形态(Treap的O(logn) ...

  7. BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】

    2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1624  Solved: 853[Submit][Status][Discu ...

  8. bzoj 2820 YY的GCD 莫比乌斯反演

    题目大意: 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 这里就抄一下别人的推断过程了 后面这个g(x) 算的方法就是在线性 ...

  9. bzoj 2820 YY的GCD(莫比乌斯反演)

    Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 kAc这种傻× ...

随机推荐

  1. 微信小程序:其中wxml和wxss的样式说明

    微信小程序:其中wxml和wxss的样式说明 一.简介 对于css不熟悉的Android程序员来说,开发微信小程序面临的一个比较困难的问题就是界面的排版了.微信小程序的排版就跟wxml和wxss有关了 ...

  2. D3学习之地图

    D3学习之地图 (2017.03.09-03.11) 地图的意义 在可视化领域中,将数据点投影和关联到地理区域上,是一个非常关键的内容(体现了可视化中利用读者自身知识常识从而加速吸收信息的原则). G ...

  3. Chemistry

    Problem A. Chemistry Input file: chemistry.in Output file: chemistry.out Time limit: 1 seconds Memor ...

  4. some words

    For we meet in an hour of change and challenge,              in a dacade of hope and fear,   in an a ...

  5. Linux 一键安装最新内核并开启 BBR 脚本

    原文链接   https://teddysun.com/489.html 请到原文链接仔细阅读后操作.建议查看过脚本内容后操作,方便理解运行过程. 使用root用户登录,运行以下命令: wget -- ...

  6. scala学习手记33 - 使用trait进行装饰

    在上一节看到了scala的在实例一级的选择性混入就不得不感叹scala在语法上的扩展性.就通过这样一个特性scala简化了很多在java中的编程概念和设计模式. 比如说在java中常用的组合,以及装饰 ...

  7. SVM-支持向量机原理详解与实践

    前言 去年由于工作项目的需要实际运用到了SVM和ANN算法,也就是支持向量机和人工神经网络算法,主要是实现项目中的实时采集图片(工业高速摄像头采集)的图像识别的这一部分功能,虽然几经波折,但是还好最终 ...

  8. js 格式化时间日期函数小结2

    方法一: // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符,  // 年(y)可以用  ...

  9. 浅谈 django Models中的跨表

    跨表操作在数据库操作非常常用,虽然其会降低读取数据的性能,但是它能节约数据在硬盘中的占用,优化数据表的结构和各自之间的关系. 在sql中,一般跨表需要用到 join 关键字 select * from ...

  10. 框架布局FrameLayout

    框架布局FrameLayout 一.简介 二.代码实例 结果图: 代码: 需要注意的代码: imageView_play.setVisibility(View.INVISIBLE); <Fram ...