P3380 【模板】二逼平衡树(树套树)

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:

  1. 查询k在区间内的排名

  2. 查询区间内排名为k的值

  3. 修改某一位值上的数值

  4. 查询k在区间内的前驱(前驱定义为严格小于x,且最大的数,若不存在输出-2147483647)

  5. 查询k在区间内的后继(后继定义为严格大于x,且最小的数,若不存在输出2147483647)

注意上面两条要求和tyvj或者bzoj不一样,请注意

输入输出格式

输入格式:

第一行两个数 n,m 表示长度为n的有序序列和m个操作

第二行有n个数,表示有序序列

下面有m行,opt表示操作标号

若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名

若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数

若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k

若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱

若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

输出格式:

对于操作1,2,4,5各输出一行,表示查询结果

输入输出样例

输入样例#1: 复制

9 6
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5
输出样例#1: 复制

2
4
3
4
9

说明

时空限制:2s,128M

n,m \leq 5\cdot {10}^4n,m≤5⋅104 保证有序序列所有值在任何时刻满足 [0, {10} ^8][0,108]

题目来源:bzoj3196 / Tyvj1730 二逼平衡树,在此鸣谢

此数据为洛谷原创。(特别提醒:此数据不保证操作5、6一定存在,故请务必考虑不存在的情况)

 #include<cstdio>
#include<iostream>
#include<algorithm>
#define maxn 50010
#define maxm 50010*400
using namespace std;
int n,m,tot,root[maxn],a[maxn],hash[maxn*],A[],B[];
struct node{int op,opl,opr,opk;}e[maxn];
struct S_T{
int cnt,lc[maxm],rc[maxm],sum[maxm];
void insert(int &k,int l,int r,int pos,int w){
if(!k)k=++cnt;
sum[k]+=w;
if(l==r)return;
int mid=(l+r)>>;
if(pos<=mid)insert(lc[k],l,mid,pos,w);
else insert(rc[k],mid+,r,pos,w);
}
int getrank(int l,int r,int w,bool ty){
int tmp=;
if(l==r){
if(!ty)return ;
else{
for(int i=;i<=A[];i++)tmp+=sum[A[i]];
for(int i=;i<=B[];i++)tmp-=sum[B[i]];
return tmp;
}
}
for(int i=;i<=A[];i++)tmp+=sum[lc[A[i]]];
for(int i=;i<=B[];i++)tmp-=sum[lc[B[i]]];
int mid=(l+r)>>;
if(w<=mid){
for(int i=;i<=A[];i++)A[i]=lc[A[i]];
for(int i=;i<=B[];i++)B[i]=lc[B[i]];
return getrank(l,mid,w,ty);
}
else {
for(int i=;i<=A[];i++)A[i]=rc[A[i]];
for(int i=;i<=B[];i++)B[i]=rc[B[i]];
return tmp+getrank(mid+,r,w,ty);
}
}
int getnum(int l,int r,int w){
if(l==r)return hash[l];
int tmp=;
for(int i=;i<=A[];i++)tmp+=sum[lc[A[i]]];
for(int i=;i<=B[];i++)tmp-=sum[lc[B[i]]];
int mid=(l+r)>>;
if(w<=tmp){
for(int i=;i<=A[];i++)A[i]=lc[A[i]];
for(int i=;i<=B[];i++)B[i]=lc[B[i]];
return getnum(l,mid,w);
}
else{
for(int i=;i<=A[];i++)A[i]=rc[A[i]];
for(int i=;i<=B[];i++)B[i]=rc[B[i]];
return getnum(mid+,r,w-tmp);
}
}
}ST;
struct B_I_T{
void add(int pos,int key,int val){
while(pos<=n){
ST.insert(root[pos],,tot,key,val);
pos+=pos&(-pos);
}
}
int qrank(int l,int r,int k,bool ty){
A[]=;while(r)A[++A[]]=root[r],r-=r&(-r);
B[]=;while(l)B[++B[]]=root[l],l-=l&(-l);
return ST.getrank(,tot,k,ty);
}
int qnum(int l,int r,int k){
A[]=;while(r)A[++A[]]=root[r],r-=r&(-r);
B[]=;while(l)B[++B[]]=root[l],l-=l&(-l);
return ST.getnum(,tot,k);
}
void modify(int pos,int w){
A[]=;int tmp=pos;
while(pos<=n)A[++A[]]=pos,pos+=pos&(-pos);
for(int i=;i<=A[];i++)ST.insert(root[A[i]],,tot,a[tmp],-);
for(int i=;i<=A[];i++)ST.insert(root[A[i]],,tot,w,);
a[tmp]=w;
}
}BIT;
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]),hash[i]=a[i];
int opt,l,r,k,tmp=n;
for(int i=;i<=m;i++){
scanf("%d",&opt);
if(opt==)scanf("%d%d",&l,&k);
else scanf("%d%d%d",&l,&r,&k);
e[i].op=opt;e[i].opl=l;e[i].opk=k;
if(opt!=)e[i].opr=r;
if(opt!=)hash[++tmp]=k;
}
sort(hash+,hash+tmp+);
tot=unique(hash+,hash+tmp+)-(hash+);
for(int i=;i<=n;i++){
a[i]=lower_bound(hash+,hash+tot+,a[i])-hash;
BIT.add(i,a[i],);
}
for(int i=;i<=m;i++)
if(e[i].op!=)e[i].opk=lower_bound(hash+,hash+tot+,e[i].opk)-hash; for(int i=;i<=m;i++){
if(e[i].op==)printf("%d\n",BIT.qrank(e[i].opl-,e[i].opr,e[i].opk,)+);
else if(e[i].op==)printf("%d\n",BIT.qnum(e[i].opl-,e[i].opr,e[i].opk));
else if(e[i].op==)BIT.modify(e[i].opl,e[i].opk);
else if(e[i].op==){
int tmp=BIT.qrank(e[i].opl-,e[i].opr,e[i].opk,);
if(!tmp)puts("-2147483647");
else printf("%d\n",BIT.qnum(e[i].opl-,e[i].opr,tmp));
}
else{
int tmp=BIT.qrank(e[i].opl-,e[i].opr,e[i].opk,);
if(tmp==e[i].opr-e[i].opl+)puts("");
else printf("%d\n",BIT.qnum(e[i].opl-,e[i].opr,tmp+));
}
}
}

洛谷P3380 【模板】二逼平衡树(树套树)(线段树+树状数组)的更多相关文章

  1. BZOJ3196 & 洛谷3380:二逼平衡树——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3196 https://www.luogu.org/problemnew/show/P3380 (题 ...

  2. 【BZOJ】3196: Tyvj 1730 二逼平衡树(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 Treap+树状数组 1WA1A,好伤心,本来是可以直接1A的,这次开始我并没有看题解,就写出 ...

  3. 洛谷P5284 [十二省联考2019]字符串问题 [后缀树]

    传送门 思路 设\(dp_i\)表示以\(i\)结尾的\(A\)串,能达到的最长长度. 然后发现这显然可以\(i\)往自己控制的\(k\)连边,\(k\)往能匹配的\(j\)连边,就是个最长路,只要建 ...

  4. 洛谷.3835.[模板]可持久化平衡树(fhq treap)

    题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...

  5. 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

  6. 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)

    [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...

  7. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

  8. 【BZOJ 3196】二逼平衡树 线段树套splay 模板题

    我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排 ...

  9. 「luogu3380」【模板】二逼平衡树(树套树)

    「luogu3380」[模板]二逼平衡树(树套树) 传送门 我写的树套树--线段树套平衡树. 线段树上的每一个节点都是一棵 \(\text{FHQ Treap}\) ,然后我们就可以根据平衡树的基本操 ...

随机推荐

  1. windows 安装 pytorch

    之前都在服务器上跑pytorch,近来发现新版本可在windows上跑了,甚是开心. 环境: windows7  python3 无CPU 步骤: 1. 确保确保python版本在3.5.3/3.6. ...

  2. python suds 调用webservice 缓存

    在linux系统中 如果webservice更新了字段 suds调用有可能缓存以前的字段或方法,对新的字段报找不到类型 TypeNotFound,或者对 新加的方法找不到该方法的错误. 当更新或添加w ...

  3. Arc076_E Connected?

    传送门 题目大意 给定$H\times W$的网格$(W,H\leq 10^8)$上的$N$对顶点,即两线交叉的交叉点而非格子内部$(N\leq 10^5)$,求是否存在至少一种方案使得每对点之间都有 ...

  4. ACM学习历程—广东工业大学2016校赛决赛-网络赛F 我是好人4(数论)

    题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=5 这个题目一看就是一道数论题,应该考虑使用容斥原理,这里对lcm进行容斥. ...

  5. bzoj 1006: 神奇的国度 MCS

    题目大意: 弦图的最小染色. 题解: 裸题. #include <vector> #include <cstdio> #include <cstring> #inc ...

  6. 【LeetCode】018 4Sum

    题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...

  7. #include <deque>

    deque \(deque\)头文件主要包括一个双端队列容器.是一个支持在两端插入两端删除的线性储存空间,与vector和queue相似.与\(vector\)比起来,\(deque\)可以在\(O( ...

  8. java多线程编程核心技术——第三章总结

    第一节等待/通知机制 1.1不使用等待/通知机制实现线程间的通讯 1.2什么是等待/通知机制 1.3等待/通知机制的实现 1.4方法wait()锁释放与notify()锁不释放 1.5当interru ...

  9. win32 获取 HotKey 控件中的内容(HKM_GETHOTKEY)

    windows给我们提供了一个对话框控件HotKey非常好用,在设置热键的时候用起来很爽,但是一直百度就是没找到在win32下怎样通过消息获取这个控件里面的内容,找到的都是用MFC封装好的控件类来操作 ...

  10. GPIO编程1:用文件IO的方式操作GPIO

    概述 通过 sysfs 方式控制 GPIO,先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO 编号,使得该 GPIO 的操作接口从内核空间暴露到用户空间,GPIO 的 ...