bzoj3223文藝平衡樹splay

2021-08-07 10:11:22 字數 1600 閱讀 4093

time limit: 10 sec  

memory limit: 128 mb

submit: 5126  

solved: 3003 [

submit][

status][

discuss]

您需要寫一種資料結構(可參考題目標題),來維護乙個有序數列,其中需要提供以下操作:

翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]的話,結果是5 2 3 4 1 

第一行為n,m n表示初始序列有n個數,這個序列依次是(1,2……n-1,n)  m表示翻轉操作次數

接下來m行每行兩個數[l,r] 資料保證 1<=l<=r<=n 

輸出一行n個數字,表示原始序列經過m次變換後的結果 

5 31 3

1 31 4

4 3 2 1 5

n,m<=100000

平衡樹

帶區間修改的平衡樹裸題

區間操作的基本套路就是對於區間l,r,把l-1擰到根,r+1擰到根的右結點,然後顯然l~r就都在r+1的左子樹里,打個延遲什麼的就很簡單了,和線段樹一樣。

然後要下放標記

下放標記可以直接在kth裡面下放,因為每次splay用到的所有節點都會在kth裡訪問一邊(旋到根)

然而如果不是這樣的題目的話最好splay之前pushup一下

為了方便一般在頭尾分別插入倆結點。

#include#include#include#include#include#define inf 0x7f7f7f7f

#define maxn 200001

#define ls t[p].ch[0]

#define rs t[p].ch[1]

#define pa t[p].f

using namespace std;

int read()

while(ch >= '0' && ch <= '9')

return x * f;

}struct node

node(int val, int fa)

}t[maxn]; int st[maxn], top, sz, root;

int wh(int p)

int newnode()

int n, m;

void update(int p)

void paint(int p)

void pushdown(int p)

}void rotate(int p)

void splay(int p, int tar)

void ins(int p, int val)

t[p = newnode()] = node(val, f);

if(f) t[f].ch[1] = p;

splay(p, 0);

}int kth(int k)

}return -1;

}void rever(int k1, int k2)

void print(int p)

{ pushdown(p);

if(ls) print(ls);

if(t[p].v != inf) cout<

BZOJ 3223 文藝平衡樹

您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是 2,4 的話,結果是5 2 3 4 1 n,m 100000 splay拿來練翻轉 這題就只用支援翻轉,很裸 翻轉區間 x,y 的操作 提取該區間,打乙個bo...

bzoj3223 文藝平衡樹

bzoj3223 文藝平衡樹 description 您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是 2,4 的話,結果是5 2 3 4 1 input 第一行為n,m n表示初始序列有n個數,這個序列依次...

bzoj 3223 文藝平衡樹

題意 對於乙個1 n的序列。進行m次區間反轉操作 求最後反轉過的區間。n,m 100000。題解 splay躶題。寫完維修數列之後感覺這種題都好寫了。反轉啥的打個標記下傳就好,記得輸出時再pushdown標記就好了 這篇題解就是說一下單旋和雙旋的簡單差別 爺爺結點就是目標的情況不討論了 zig za...