今天调了一个早上哈哈哈,不过因为\(Splay\),常数比较大

洛谷的评测记录:

\(Code\ Below:\)

#include <bits/stdc++.h>
#define ll long long
#define mid (l+r>>1)
using namespace std;
const int maxn=4000010;
const int inf=2147483647;
int n,m,sz,ans,Max;
int a[maxn],ch[maxn][2],fa[maxn],siz[maxn],cnt[maxn],key[maxn],rt[maxn]; inline void splayclear(int x){
fa[x]=ch[x][0]=ch[x][1]=siz[x]=cnt[x]=key[x]=0;
}
inline bool get(int x){
return ch[fa[x]][1]==x;
}
inline void update(int x){
siz[x]=(ch[x][0]?siz[ch[x][0]]:0)+(ch[x][1]?siz[ch[x][1]]:0)+cnt[x];
}
inline void rotate(int x){
int y=fa[x],z=fa[y],k=get(x);
ch[y][k]=ch[x][k^1];fa[ch[y][k]]=y;
ch[x][k^1]=y;fa[y]=x;fa[x]=z;
if(z) ch[z][ch[z][1]==y]=x;
update(y);update(x);
}
inline void splay(int i,int x,int top){
for(int y,z;fa[x]!=top;rotate(x)){
y=fa[x],z=fa[y];
if(z!=top) rotate(get(x)==get(y)?y:x);
}
if(!top) rt[i]=x;
}
inline void splayinsert(int i,int val){
int x=rt[i],y;
if(!rt[i]){
rt[i]=x=++sz;fa[x]=ch[x][0]=ch[x][1]=0;
key[x]=val;siz[x]=cnt[x]=1;return;
}
while(1){
if(key[x]==val){cnt[x]++;update(y);break;}
y=x;x=ch[x][key[x]<val];
if(x==0){
x=++sz;key[x]=val;siz[x]=cnt[x]=1;
ch[y][key[y]<val]=x;fa[x]=y;
update(y);break;
}
}
splay(i,x,0);
}
inline int splayrank(int i,int val){
int x=rt[i],ret=0;
while(x>0){
if(val<key[x]) x=ch[x][0];
else {
ret+=(ch[x][0]?siz[ch[x][0]]:0);
if(val==key[x]) return ret;
ret+=cnt[x];x=ch[x][1];
}
}
return ret;
}
inline int splayfind(int i,int val){
int x=rt[i];
while(x>0){
if(val==key[x]){splay(i,x,0);return x;}
x=ch[x][key[x]<val];
}
}
inline int splaypre(int i){int x=ch[rt[i]][0];while(ch[x][1])x=ch[x][1];return x;}
inline int splaysuc(int i){int x=ch[rt[i]][1];while(ch[x][0])x=ch[x][0];return x;}
inline void splaydel(int i,int val){
int x=splayfind(i,val),y=rt[i];
if(cnt[x]>1){cnt[x]--;update(x);return;}
if(!ch[x][0]&&!ch[x][1]){splayclear(rt[i]);rt[i]=0;return;}
if(!ch[x][0]){y=ch[x][1];rt[i]=y;fa[y]=0;return;}
if(!ch[x][1]){y=ch[x][0];rt[i]=y;fa[y]=0;return;}
splay(i,splaypre(i),0);
ch[rt[i]][1]=ch[y][1];fa[ch[y][1]]=rt[i];
splayclear(y);update(rt[i]);
}
inline int splaygetpre(int i,int val){
int x=rt[i];
while(x>0){
if(val<=key[x]) x=ch[x][0];
else {
if(key[x]>ans) ans=key[x];
x=ch[x][1];
}
}
return ans;
}
inline int splaygetsuc(int i,int val){
int x=rt[i];
while(x>0){
if(val>=key[x]) x=ch[x][1];
else {
if(key[x]<ans) ans=key[x];
x=ch[x][0];
}
}
return ans;
} inline void seginsert(int l,int r,int rt,int x,int val){
splayinsert(rt,val);
if(l == r) return;
if(x <= mid) seginsert(l,mid,rt<<1,x,val);
else seginsert(mid+1,r,rt<<1|1,x,val);
}
inline void segrank(int L,int R,int val,int l,int r,int rt){
if(L <= l && r <= R){ans+=splayrank(rt,val);return;}
if(L <= mid) segrank(L,R,val,l,mid,rt<<1);
if(R > mid) segrank(L,R,val,mid+1,r,rt<<1|1);
}
inline void segchange(int l,int r,int rt,int x,int val){
splaydel(rt,a[x]);splayinsert(rt,val);
if(l == r){a[x]=val;return;}
if(x <= mid) segchange(l,mid,rt<<1,x,val);
else segchange(mid+1,r,rt<<1|1,x,val);
}
inline void segpre(int L,int R,int val,int l,int r,int rt){
if(L <= l && r <= R){ans=max(ans,splaygetpre(rt,val));return;}
if(L <= mid) segpre(L,R,val,l,mid,rt<<1);
if(R > mid) segpre(L,R,val,mid+1,r,rt<<1|1);
}
inline void segsuc(int L,int R,int val,int l,int r,int rt){
if(L <= l && r <= R){ans=min(ans,splaygetsuc(rt,val));return;}
if(L <= mid) segsuc(L,R,val,l,mid,rt<<1);
if(R > mid) segsuc(L,R,val,mid+1,r,rt<<1|1);
}
inline int getkth(int L,int R,int k){
int l=0,r=Max+1,Mid;
while(l<r){
Mid=l+r>>1;ans=0;
segrank(L,R,Mid,1,n,1);
if(ans<k) l=Mid+1;
else r=Mid;
}
return l-1;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
seginsert(1,n,1,i,a[i]);
Max=max(Max,a[i]);
}
int opt,l,r,val;
while(m--){
scanf("%d%d%d",&opt,&l,&r);
switch(opt){
case 1:scanf("%d",&val);ans=0;segrank(l,r,val,1,n,1);printf("%d\n",ans+1);break;
case 2:scanf("%d",&val);printf("%d\n",getkth(l,r,val));break;
case 3:segchange(1,n,1,l,r);break;
case 4:scanf("%d",&val);ans=-inf;segpre(l,r,val,1,n,1);printf("%d\n",ans);break;
case 5:scanf("%d",&val);ans=inf;segsuc(l,r,val,1,n,1);printf("%d\n",ans);break;
}
}
return 0;
}

[学习笔记]树套树 线段树套Splay的更多相关文章

  1. ACM学习笔记:可持久化线段树

    title : 可持久化线段树 date : 2021-8-18 tags : 数据结构,ACM 可持久化线段树 可以用来解决线段树存储历史状态的问题. 我们在进行单点修改后,线段树只有logn个(一 ...

  2. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  3. BZOJ 3218(a + b Problem-二分图套值域线段树)

    出这题的人是怎么想出来的…… 言归正传,这题是二分图套值域线段树. 首先经过 @Vfleaking的神奇建图后,把图拆成二分图, 不妨利用有向图最小割的性质建图(以前我一直以为最小割和边的方向无关,可 ...

  4. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  5. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  6. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  7. 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex

    题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...

  8. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

  9. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  10. 差分+树状数组 线段树【P2357】 守墓人

    题目描述-->p2357 守墓人 敲了一遍线段树,水过. 树状数组分析 主要思路: 差分 简单介绍一下差分(详细概念太麻烦,看下面. 给定一个数组 7 8 6 5 1 8 18 20 35 // ...

随机推荐

  1. PDO beginTransaction (),exec(),commit ()

    $dsn = 'sqlsrv:server=.\SQLExpress;Database=thinkphp'; $user = 'admin'; $password = 'pass1234'; try ...

  2. Django的学习(五)————实战问题

    一.多参数问题: 首先是在添加一个新的参数,其次在url中把这个id传递过去 def article_page(request, article_id): article = models.Artic ...

  3. 2018.12.15 spoj Substrings(后缀自动机)

    传送门 后缀自动机基础题. 求长度为iii的子串出现次数的最大值. 对原串建出samsamsam,然后用sizsizsiz更新每个maxlenmaxlenmaxlen的答案. 然后由于后缀链接将其转化 ...

  4. 2018.11.01 NOIP训练 梭哈(模拟)

    传送门 这题貌似不考智商啊. 直接按题意写就可以了. 事实上把牌从小到大排序之后写起来很舒服的. 然后就是有些地方可以人脑减代码量和判断次数. (提示:满堂红和某几种同类型的牌的大小判断) 然后注意A ...

  5. 2018.06.27The Windy's(费用流)

    The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6003 Accepted: 2484 Descripti ...

  6. ThinkPHP redirect 传参

    重定向带参 $this->redirect('pay/under_line_success',array('order_id'=>$stuInfo),5,'页面跳转中….'); 第一个参数 ...

  7. Educational Codeforces Round 61 F 思维 + 区间dp

    https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...

  8. illustrator画梯形

    1.在空白文档上先绘制出一个长方形: 2.用鼠标点击工具箱中”自由变换“工具: 3.用鼠标指向长方形四个顶点中的任意一个,当鼠标的箭头变为相反反方向的双箭头时,再按住鼠标左键不要松手, 同时按住[sh ...

  9. MySQL处理表字段小技巧

    MySQL利用正则函数替换值 update dateTest set date=REPLACE(date,'/','') where date REGEXP '\/'; SQL语句讲解: -- 将 所 ...

  10. Win10通知区域图标设置;windows10系统图标合并;Windows10系统通知合并

    1.一直喜欢Windows7的通知图标合并 2.通过查阅找到方法 a.输入命令语句   win+R  :shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9} 回 ...