傳送門
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行每行兩個數 ...