查詢k在區間內的排名
查詢區間內排名為k的值
修改某一位值上的數值
查詢k在區間內的前驅(前驅定義為嚴格小於x,且最大的數,若不存在輸出-2147483647)
查詢k在區間內的後繼(後繼定義為嚴格大於x,且最小的數,若不存在輸出2147483647)
輸入格式:
第一行兩個數 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 64 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: 複製
24349
時空限制:2s,128m
n,m \leq 5\cdot ^4n,m≤5⋅104 保證有序序列所有值在任何時刻滿足 [0, ^8][0,108]
複習了一下樹套樹
感覺很套路啊qwq,
然而不想重寫, 所以就對著以前的抄了一遍。
//luogu-judger-enable-o2
#include#include
#include
#include
using
namespace
std;
const
int maxn = 2000001
;inline
intread()
while(c >= '
0' && c <= '9')
return x *f;
}#define ls(k) s[k].ch[0]
#define rs(k) s[k].ch[1]
struct
sp s[maxn];
intsz;
inline
void pushup(int k)
inline
int ident(int x)
inline
void connect(int x, int f, int
how)
inline
void rotate(int &root,int x)
inline
void splay(int &root, int x, int to)
}inline
void insert(int &k, int c)
if(s[k].num==c) s[k].rev++;
else
if(s[k].num < c) insert(rs(k), c), s[rs(k)].fa =k;
else insert(ls(k), c), s[ls(k)].fa =k;
pushup(k);
}inline
int getpre(int k,int val)
return
ret;
}inline
int getsuc(int k,int
val)
return
ret;
}inline
int getk(int k,int
val)
#define ls k << 1
#define rs k << 1 | 1
struct
node t[maxn];
inline
void pushup_s(int k)
inline
void build(int k,int l,int r)
inline
void delet(int &k, int val)
else
}inline
void build(int k, int pos, int x)
int mid = (t[k].l + t[k].r) >> 1
;
if(pos <=mid) build(ls, pos, x);
if(pos >mid) build(rs, pos, x);
pushup_s(k);
//別忘了上傳線段樹標記
}int newnode(int val, int
f) inline
void dfsseg(int k)
inline
int getmax(int k,int l,int r)
inline
int getmin(int k,int l,int r)
inline
int query_order(int k, int l, int r, int val)
int mid = (t[k].l + t[k].r) >> 1, ret = 0
;
if(l <= mid) ret +=query_order(ls, l, r, val);
if(r > mid) ret +=query_order(rs, l, r, val);
return
ret;
}inline
void modify(int k,int pos,int pre,int now)
int mid = (t[k].l + t[k].r) >> 1
;
if(pos <=mid) modify(ls , pos, pre, now);
if(pos >mid) modify(rs , pos, pre, now);
pushup_s(k);
//別忘了上傳標記!
}inline
int query_pre(int k,int l,int r,int val)
inline
int query_suc(int k,int l,int r,int val)
inline
int querynum(int l,int r,int val)
return
ret;
}int
n, m;
intdate[maxn];
intmain()
if(opt == 2)
if(opt==3)
if(opt==4
)
if(opt == 5
) }
return0;
}
洛谷P3380 模板 二逼平衡樹(樹套樹)
查詢k在區間內的排名 查詢區間內排名為k的值 修改某一位值上的數值 查詢k在區間內的前驅 前驅定義為嚴格小於x,且最大的數,若不存在輸出 2147483647 查詢k在區間內的後繼 後繼定義為嚴格大於x,且最小的數,若不存在輸出2147483647 輸入格式 第一行兩個數 n,m 表示長度為n的有序...
洛谷P3380 模板 二逼平衡樹(樹套樹)
查詢k在區間內的排名 查詢區間內排名為k的值 修改某一位值上的數值 查詢k在區間內的前驅 前驅定義為嚴格小於x,且最大的數,若不存在輸出 2147483647 查詢k在區間內的後繼 後繼定義為嚴格大於x,且最小的數,若不存在輸出2147483647 輸入格式 第一行兩個數 n,m 表示長度為n的有序...
洛谷 P3380 模板 二逼平衡樹(樹套樹)
其實比想象中的好理解啊 所謂樹套樹,就是在一棵樹的基礎上,每乙個節點再維護一棵樹 說白了,就是為了實現自己想要的操作和優秀的時間複雜度,來人為的增加一些毒瘤資料結構來維護一些什麼東西 比如說這道題 如果只求乙個區間內的乙個數是否是最大值或者最小值,我們顯然可以用線段樹輕輕鬆鬆地解決這個問題 但是現在...