bzoj3223 Tyvj 1729 文藝平衡樹

2021-07-28 02:33:03 字數 1490 閱讀 3386

傳送門

description

input

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

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

output

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

sample input

5 31 3

1 31 4

sample output

4 3 2 1 5

hint

n,m<=100000

source

平衡樹splay**好~

第二次寫splay,手好生啊

相對普通平衡樹那道題少了不少操作,但是多了區間翻轉操作,所以我們要在原有的基礎上增加翻轉標記,每次碰到標記就pushdown並且交換左右子樹。

但是還有乙個問題:在進行翻轉操作的時候,由於我們的方法是將 l-1 splay到根上,將 r+1 splay到根的右兒子上,再對 r+1 的左子樹進行修改,而當操作範圍有1或n的時候,這種方法就失效了,怎麼辦呢?

我們可以增增兩個虛擬節點,其size值也為1,操作區間[l,r]的時候變為操作[l+1,r+1]就可以了

輸出:進行中序遍歷,只要是合法的節點就輸出該節點的值

ps:蒟蒻在一開始雖然加了虛擬節點但是未給其賦size值,結果每次修改[1,?]的時候要查詢第0大的節點,返回的都是null節點,qaq

code:

#includestruct node

void update()

void swap()

void pushdown();

void setch(int wh,node *child);

}pool[100010],*root,*null;

void node::setch(int wh,node *child)

void node::pushdown()

if(ch[0]!=null) ch[0]->rev^=1;

if(ch[1]!=null) ch[1]->rev^=1;

rev=0;

swap();

}int n,m,x,y,tot;

inline node *getnew(int value)

inline node *build(int l,int r)

inline void rotate(node *now)

inline void splay(node *now,node *tar)

if(tar==null) root=now;

}inline node *find(int num)

}inline void reverse(int l,int r)

void dfs(node *now)

int main()

dfs(root);

return 0;

}

BZOJ3223 Tyvj1729 文藝平衡樹

題目大意 一開始有個數列 有q 次區間翻轉操作。請輸出最後的序列。1 n,q 105一道寫出blog都不知道有什麼意義的splay大裸題。splay在我還是pas黨的時候寫過,現在已經忘了個精光。就當做是模板記錄,以及作為自己終於下定決心怒剛專題的紀念吧。什麼你告訴我你不知道這題怎麼做?那我也沒辦法...

bzoj3223 Tyvj1729 文藝平衡樹

time limit 10 secmemory limit 128 mb submit 3014solved 1722 您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 翻轉乙個區間,例如原有序序列是54321,翻轉區間是 2,4 的話,結果是52341 第一行為n,m...

bzoj3223 Tyvj 1729 文藝平衡樹

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