做了一套簡單的練習後,用splay處理區間問題就變得非常容易了。
總的來說,所有的splay有關,涉及區間的問題,都會基於select操作(其實就是根據排名找點)
node * find_id(node *x,int k)
我寫的遞迴版本,比較容易理解,但最好改為迴圈實現。
然後,有了這一操作,我們可以將splay tree中的任意乙個區間「提取」出來
例如翻轉操作:
void rev(int k,int
len)
這樣的做法很顯然需要預設兩個哨兵節點,乙個在最前,乙個最後。
其實所有的區間操作,無非就是這樣乙個既定的套路,唯一有所不同的,也只有在pushup和pushdown中才能體現。
也正是因此,pushup和pushdown的操作具有很強的靈活性,分別概述過於複雜,我在這裡就簡單提及一下這兩個操作的注意事項:
pushup操作的目的,是將子節點的資訊重新反饋到當前節點。因此任何涉及更改子節點的資訊後,都必須使用pushup操作。是乙個上傳的過程。
pushdown則與之相反,是將當前節點的資訊(懶標記為主)下傳給子節點,必須遵守乙個原則:即與pushup操作不衝突。也就是說,任何時候,當你使用一次pushdown,再做一次pushup,是不能夠將pushdown操作所改變的資訊抹去的。這一點在本題很有體現:在區間賦值操作中,如果僅僅更新當前節點,是不能夠滿足要求的,因為當再做一次pushup操作時,子節點的懶標記並未處理,造成當前節點又被恢復原樣。以上就是splay處理區間問題的方法,
對於節點維護哪些資訊,可以當做線段樹來考慮,因為同為二叉樹,線段樹和平衡樹有很多相同之處。
對於本題的做法,就再簡單提及一點:
本題必須使用釋放空間的方式來完成刪除,否則會t
成套路的方法,沒必要刷過多的題,做一兩道經典的就可以了。
#include
#include
#include
#include
#include
#define sf scanf
#define pf printf
#define maxn 500100
#define inf 0x3fffffff
using namespace std;
struct nodetree[maxn];
node *root,*nil=&tree[0],*ncnt=&tree[1];
bool flag=0;
stack
emt;
int a[maxn];
void
read(int &x)
x=c-'0';
while(c=getchar(),c!=eof&&c>='0'&&c<='9')
x=x*10+c-'0';
if(flag)
x=-x;
}node *newnode(int val)
void pushup(node *x)
void pushdownx(node *x)
if(x->flag!=inf)
}void pushdown(node *x)
if(x->flag!=inf)
if(x->ch[0]!=nil)
pushdownx(x->ch[0]);
if(x->ch[1]!=nil)
pushdownx(x->ch[1]);
}void
rotate(node *x)
void splay(node *x,node *rt)
else
}}node * find_id(node *x,int k)
node * findnext(node *x,int d)
return x;
}void build(int l,int r,node *fa,int d)
node * ins(int k,int val)
node *y=findnext(x->ch[1],0);
splay(y,x);
y->ch[0]=newnode(val);
y->ch[0]->fa=y;
pushup(y);
pushup(x);
return y->ch[0];
}void
fre(node *x)
void
del(int k,int len)
void
mak(int k,int len,int val)
void
rev(int k,int len)
void
get(int k,int len)
void
mas()
void print(node *x)]\n ",x-tree,x->key,x->maxs,x->ch[0]-tree,x->ch[1]-tree,x->fa-tree);
pf("%d ",x->key);
print(x->ch[1]);
}int n,m;
int k,len,val;
char s[20];
int main()
node *x1=x;
while(x!=nil)
splay(x1,nil);
}else
if(s[0]=='d')
else
if(s[0]=='r')
else
if(s[0]=='g')
else
if(s[2]=='k')
else
//print(root);
//pf("\n-----------------------------\n");}}
2017就是我們的喜悅,
我們的挫敗,
我們的成就,
我們的悔恨,
是我們封存的標本。
幸好,明天我們還會忘記新的事物,
所以我們不害怕時間,
時間會向前奔跑,
我們也會。
資料結構 1 5章
一 資料結構以及相關概念的定義 二 抽象資料型別 三 演算法的時間複雜度和空間複雜度 一 線性表的定義和基本操作 二 線性表的實現 1.順序儲存結構 define list init size 100 線性表儲存空間的初始分配量 define listincrement 10 線性表儲存空間的分配增...
15 資料結構和演算法應用
大問題拆分成規模小的問題,往往用到遞迴 八皇后深度優先搜尋法 不一定得到的是最優解,價效比方案 判斷貪心法,看每一步是不是最優解,而最終的結果不見得是最優解 0 1揹包問題,就是如下,乙個揹包裝東西只能裝一種 邏輯複雜,跟分治法類似 動態規劃法特點,查表,就是拆分問題,將問題記錄到表,然後查表 我們...
資料結構基礎 15 基數排序
基數排序是一種借助 多關鍵字排序 的思想來實現 單關鍵字排序 的內部排序演算法。實現多關鍵字排序通常有兩種作法 最低位優先法 lsd 先對k 0 進行排序,並按 k 0 的不同值將記錄序列分成若干子串行之後,分別對 k 1 進行排序,k d 1 依次類推,直至最後對最次位關鍵字排序完成為止。最高位優...