題目鏈結 kth number
主 席樹
主席樹主席
樹主席樹模板題
關於主席樹沒啥好講的,其實就是動態開點+線段樹
#pragma gcc optimize(2)
#include
#include
#include
using namespace std;
typedef
long
long ll;
const
int maxn =
1e5+5;
const
int mod =
1e9+9;
int case =1;
int n, m, root[maxn]
, tot;
struct nodetr[maxn<<5]
;void
pushup
(int rt)
void
build
(int
&rt,
int l,
int r)
int mid =
(l + r)/2
;build
(tr[rt]
.l, l, mid)
;build
(tr[rt]
.r, mid+
1, r)
;pushup
(rt);}
void
insert
(int
&rt,
int pr,
int pos,
int l,
int r)
tr[rt]
= tr[pr]
;int mid =
(l + r)/2
;if(pos <= mid)
insert
(tr[rt]
.l, tr[pr]
.l, pos, l, mid)
;else
insert
(tr[rt]
.r, tr[pr]
.r, pos, mid+
1, r)
;pushup
(rt);}
vector<
int>ve;
int cc[maxn]
;int
getid
(int x)
intquery
(int lc,
int rc,
int k,
int l,
int r)
void
solve()
sort
(ve.
begin()
, ve.
end())
; ve.
erase
(unique
(ve.
begin()
, ve.
end())
, ve.
end())
;int s = ve.
size()
;for
(int i =
1; i <= n; i++
)for
(int i =
1; i <= m; i++
)return;}
intmain()
return0;
}
整體二
分整體二分
整體二分
整體二分中提現了分治的思想,但不是演算法的關鍵,關鍵在分治的過程中對權值二分。
對於小於mid的更新就用樹狀陣列更新,並且對於已經可以確定範圍的詢問也進行劃分。把小於mid的詢問和更新分成一組,把大於mid的詢問減去左半部分已知的詢問和大於mid的詢問放在一起。
if
(cc[i]
.op)
else
直到遞迴到二分的權值上界等於下界的時候在這個範圍內的所有詢問的答案也必然是此時的權值。f
(l>r || l>r)
return;if
(l==r)
最後就是分組後分治繼續二分for
(int i=
1;i<=cnt1;i++)if
(!t1[i]
.op) tree.
update
(t1[i]
.pos,
-t1[i]
.y);
for(
int i=
1;i<=cnt1;i++
) cc[l+i-1]
=t1[i]
;for
(int i=
1;i<=cnt2;i++
) cc[l+cnt1+i-1]
=t2[i]
;cal
(l, mid, l, l+cnt1-1)
;cal
(mid+
1, r, l+cnt1, r)
;
細節:
樹狀陣列每次清零別用memset
權值的上下界和序列的指標變數別搞混了。。。
#pragma gcc optimize(2)
#include
using namespace std;
const
int maxn =
5e5+5;
typedef
long
long ll;
const ll mod =
1e9+7;
int case =1;
int n, m;
struct nodecc[maxn]
, t1[maxn]
, t2[maxn]
;int res[maxn]
;struct tree
void
update
(int pos,
int val)
}int
query
(int pos)
return res;
}}tree;
void
cal(
int l,
int r,
int l,
int r)
int mid=
(l+r)
>>
1, cnt1=
0, cnt2=0;
for(
int i = l; i <= r; i++
)else
}for
(int i=
1;i<=cnt1;i++)if
(!t1[i]
.op) tree.
update
(t1[i]
.pos,
-t1[i]
.y);
for(
int i=
1;i<=cnt1;i++
) cc[l+i-1]
=t1[i]
;for
(int i=
1;i<=cnt2;i++
) cc[l+cnt1+i-1]
=t2[i]
;cal
(l, mid, l, l+cnt1-1)
;cal
(mid+
1, r, l+cnt1, r);}
void
solve()
for(
int i =
1; i <= m; i++
)cal(-
1e9,
1e9,
1, cnt)
;for
(int i =
1; i <= m; i++
)printf
("%d\n"
, res[i]);
return;}
intmain()
return0;
}
主席樹模板 POJ2104
離散化 對陣列排完序後用unique去重,unique返回的是去重後的陣列的末位址,減去第乙個元素的位址就能得到去重後的陣列大小,用lower bound查詢原數字在排序去重後的序列中的位序,用位序代替數字完成離散化。include include using namespace std defin...
主席樹模板(poj2104)
主席樹是可持久化線段樹,可以記錄線段樹的歷史版本。中和線段樹不同的是,l,r記錄的是左右子樹編號,因為普通的線段樹版本中,左右子樹自然就是o 1和o 1 1,但是主席樹中並不保證這個特性,所以需要記錄一下。是 include include include include include using...
Poj 2104 主席樹入門
題目 靜態查詢區間第 大 主席樹入門題目,之前看的很多資料一上來就是動態區間第 大,看得很費勁,後來找了個寫得清晰的,感覺靜態的還不算難,也不長 author cwind pragma comment linker,stack 102400000,102400000 include include ...