传送门

题意

给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种:

  1. 查询 $ k $ 在区间 $ [l,r] $ 内的排名
  2. 查询区间 $ [l,r] $ 内排名为 $ k $ 的值
  3. 将 $ a[p] $ 修改为 $ k $
  4. 查询 $ k $ 在区间 $ [l,r] $ 内的前驱(前驱定义为小于 $ k $ ,且最大的数)
  5. 查询 $ k $ 在区间 $ [l,r] $ 内的后继(后继定义为大于 $ k $ ,且最小的数)

题解

线段树套splay。

先将 $ n $ 个数插入线段树:对于每个 $ a[i] $,将线段树上到位置 $ i $ 的叶子节点的路径上的所有splay插入元素 $ a[i] $ 。

操作1:区间 $ [l,r] $ 在线段树上对应了若干棵splay,将这些splay中小于 $ k $ 的元素个数累加,记为 $ sum $ ,$ sum+1 $ 即为答案。

操作2:二分这个元素的值,然后进行操作1得到当前rank,对应地调整答案。

操作3:将线段树上到位置 $ p $ 的叶子节点的路径上的所有splay删除 $ a[p] $ ,再插入 $ k $ ,然后更新 $ a[p] = k $ 。

操作4:将区间 $ [l,r] $ 对应的所有splay中查询到的 $ k $ 的前驱取 $ max $ 即可。

操作5:将区间 $ [l,r] $ 对应的所有splay中查询到的 $ k $ 的后继取 $ min $ 即可。

最后,纪念一下我用pbds加map封装的的假splay......QAQ

还有就是因为b站g++版本太老,null_type会CE,要改成null_mapped_type

AC Code

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define MAX_N 50005
#define MAX_V 200005
#define INF 2147483647 using namespace std;
using namespace __gnu_pbds; typedef tree<pair<int,int>,null_mapped_type,less<pair<int,int> >,rb_tree_tag,tree_order_statistics_node_update> Tree;
typedef Tree::iterator git; struct Splay
{
Tree t;
map<int,int> mp;
void ins(int x)
{
t.insert(make_pair(x,mp[x]=mp[x]+1));
}
void del(int x)
{
t.erase(make_pair(x,mp[x])),mp[x]=mp[x]-1;
}
int pre(int x)
{
if(t.empty()) return -INF;
git it=t.lower_bound(make_pair(x,0));
if(it==t.begin()) return -INF;
return (--it)->first;
}
int suc(int x)
{
if(t.empty()) return INF;
git it=t.upper_bound(make_pair(x,INF));
if(it==t.end()) return INF;
return it->first;
}
int kth(int x)
{
return t.find_by_order(x-1)->first;
}
int rk(int x)
{
return t.order_of_key(make_pair(x,1))+1;
}
}; int n,m;
int a[MAX_N];
Splay t[MAX_V]; void ins(int p,int k,int l,int r,int x)
{
t[k].ins(x);
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) ins(p,k*2+1,l,mid,x);
else ins(p,k*2+2,mid+1,r,x);
} int getrk(int a,int b,int k,int l,int r,int x)
{
if(a<=l && r<=b) return t[k].rk(x)-1;
int mid=(l+r)>>1,ans=0;
if(a<=mid) ans+=getrk(a,b,k*2+1,l,mid,x);
if(b>mid) ans+=getrk(a,b,k*2+2,mid+1,r,x);
return ans;
} int getx(int a,int b,int k)
{
int l=0,r=INF;
while(r-l>1)
{
int mid=(l+r)>>1;
if(getrk(a,b,0,1,n,mid)<=k-1) l=mid;
else r=mid;
}
return l;
} void upd(int p,int k,int l,int r,int x)
{
t[k].del(a[p]),t[k].ins(x);
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) upd(p,k*2+1,l,mid,x);
else upd(p,k*2+2,mid+1,r,x);
} int getpre(int a,int b,int k,int l,int r,int x)
{
if(a<=l && r<=b) return t[k].pre(x);
int mid=(l+r)>>1,ans=-INF;
if(a<=mid) ans=max(ans,getpre(a,b,k*2+1,l,mid,x));
if(b>mid) ans=max(ans,getpre(a,b,k*2+2,mid+1,r,x));
return ans;
} int getsuc(int a,int b,int k,int l,int r,int x)
{
if(a<=l && r<=b) return t[k].suc(x);
int mid=(l+r)>>1,ans=INF;
if(a<=mid) ans=min(ans,getsuc(a,b,k*2+1,l,mid,x));
if(b>mid) ans=min(ans,getsuc(a,b,k*2+2,mid+1,r,x));
return ans;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),ins(i,0,1,n,a[i]);
int opt,l,r,k,p;
while(m--)
{
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",getrk(l,r,0,1,n,k)+1);
}
if(opt==2)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",getx(l,r,k));
}
if(opt==3)
{
scanf("%d%d",&p,&k);
upd(p,0,1,n,k),a[p]=k;
}
if(opt==4)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",getpre(l,r,0,1,n,k));
}
if(opt==5)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",getsuc(l,r,0,1,n,k));
}
}
}

BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay的更多相关文章

  1. BZOJ - 3196 Tyvj 1730 二逼平衡树 (线段树套treap)

    题目链接 区间线段树套treap,空间复杂度$O(nlogn)$,时间复杂度除了查询区间k大是$O(log^3n)$以外都是$O(log^2n)$的. (据说线段树套线段树.树状数组套线段树也能过?) ...

  2. [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树

    题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...

  3. 【bzoj3196】Tyvj 1730 二逼平衡树 线段树套Treap

    题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义 ...

  4. [bzoj3196][Tyvj 1730][二逼平衡树] (线段树套treap)

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...

  5. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1807  Solved: 772[Submit][Stat ...

  6. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  7. BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )

    这道题做法应该很多吧.... 我用了线段树套treap.... -------------------------------------------------------------------- ...

  8. bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题面; 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Se ...

  9. BZOJ 3196 Tyvj 1730 二逼平衡树 树套树 线段树 treap

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196 http://hzwer.com/2734.html 线段树套treap,似乎splay也可以 ...

随机推荐

  1. delphi---EHlib第三方插件----TDBGridEH,TDBNumberEditEh,TDBComboBoxEh

    一.TDBGridEH 1.多选 行 options->dgMultiSelect 2.列字体改变颜色,OnDrawColumnCell写下方法. if Column.FieldName='价格 ...

  2. Oracle存储——逻辑结构

    Oracle 数存储——物理结构 Oracle存储结构:物理结构+逻辑结构 Oracle 数据库存储逻辑结构 Oracle Schema Objects(Schema Object Storage A ...

  3. <2014 03 18> Term BreakPoint

  4. HTML里引号的输出与显示

    关于输入框中显示双引号和单引号 前台显示解决办法: 方法一: 单引号<input type="text" value="'"> 双引号<inp ...

  5. 11.Query an Array of Embedded Documents-官方文档摘录

    总结 1.插入数据 db.inventory.insertMany( [ { item: "journal", instock: [ { warehouse: "A&qu ...

  6. linux虚拟机连不上网络

    1.修改文件ifcfg-ens33 # 切换目录 [root@localhost ~]# cd /etc/sysconfig/network-scripts/ # 将ONBOOT修改为yes [roo ...

  7. 【我的Android进阶之旅】 高效的设计稿标注及测量工具Markman介绍

    前言 最近有个烦恼是UI设计师可能太忙了,经常给出的UI设计稿中有很多地方都没有标注,比如长度和颜色值等.这个时候每次都要通过RTX来联系UI设计师或者直接跑到UI设计师面前,喊他重新标注一下,特别影 ...

  8. 【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法

    错误描述 今天使用第三方的so库时候,调用JNI方法时出现了错误.报错如下所示: 11-01 16:39:20.979 4669-4669/com.netease.xtc.cloudmusic E/a ...

  9. 注册tomcat为windows服务(转载)

    第一部分 应用场景 需要服务器上Tomcat不显示启动窗口 需要服务器上Tomcat开机自启动 ... 第二部分 配置过程 一.修改配置文件 1 {Tomcat_HOME}/bin/service.b ...

  10. NUnit.Framework的使用方法演示

    using NUnit.Framework; namespace CheckExcel { [TestFixture] public class TestExcelHelper { /// <s ...