求靜態區間第k小數。
即給定陣列a和乙個區間,求[l,r]中第k小的數。
假設大小為n的陣列內的值恰好為1~n的排列。比如大小為4的陣列為:4,2,1,3.
要想將其他陣列轉化為上述簡化問題,只需進行離散即可。即將原陣列排序,將對應的值與排序後的下標對應起來。用下標來表示原來的值。
vector<
int> v;
intgetid
(int k)
for(
int i=
1;i<=n;i++
)sort
(v.begin()
,v.end()
);v.erase
(unique
(v.begin()
,v.end()
),v.
end())
;
設rt[i]表示由陣列前i個元素組成的線段樹的根結點。結點為乙個結構體,內含l,r,sum。l、r表示該結點的左右子結點,sum表示以該結點為根的子樹所含陣列內元素的個數。
(1)建立一顆空樹,預設陣列值都為0
void
build
(int
&o,int l,
int r)
//建立一顆空樹
void
update
(int l,
int r,
int&now,
int last,
int k)
int
query
(int l,
int r,
int x,
int y,
int k)
//查詢區間【x,y】中第小的數
//poj2104
#include
#include
#include
#include
using
namespace std;
const
int maxn=
1e5+
100;
int a[maxn]
;int rt[maxn]
;//rt[i]表示由陣列前i個元素組成的線段樹的根結點
struct node
t[maxn*20]
;int tot=0;
//結點編號
vector<
int> v;
intgetid
(int k)
void
build
(int
&o,int l,
int r)
//建立一顆空樹
void
update
(int l,
int r,
int&now,
int last,
int k)
intquery
(int l,
int r,
int x,
int y,
int k)
//查詢區間【x,y】中第小的數
intmain()
//build(,1,n);
sort
(v.begin()
,v.end()
);v.
erase
(unique
(v.begin()
,v.end()
),v.
end())
;build
(rt[0]
,1,n);
for(
int i=
1;i<=n;i++
)update(1
,n,rt[i]
,rt[i-1]
,getid
(a[i]))
;while
(m--)}
return0;
}
主席樹 模板
思想 主席樹就是一顆持久化線段樹,為什麼叫持久化了,因為它可以儲存之前的線段樹版本,並且可以拿來用,從而優化空間.至於為什麼叫主席樹了,大概是因為發明這個演算法的人的名字的緣故吧 詳細說說 主席樹是一種離線資料結構,是由很多棵線段樹組成的。第i棵線段樹存的是前i個數的資訊 每乙個線段存數字的出現次數...
主席樹模板
維護n棵1 i的字首權值線段樹,每次查詢減一下就好了。poj 2104就是模板題,裸的靜態第k大,需要先離散化,不會的就用lower bound 多試試,研究研究應該就能懂。include include include include using namespace std const int m...
模板 主席樹
譴責奶人的hsz巨神 靜態版本 求區間第k大 可持久化也沒那麼高大上嘛,主席樹本質上就是多棵線段樹,求第k大就類似平衡樹的第k大。stay foolish,stay hungry,stay young,stay include include include include using namesp...