題目鏈結
題意:給你乙個n
nn個點的樹,每個點有乙個範圍是1−n
1-n1−
n的權值,可能會有重複。每次問你乙個點的子樹內與它深度差不超過x
xx題解:
感覺一看就很線段樹合併,因為如果沒有不同權值的限制,只問乙個點子樹內與它深度差不超過x
xx的點的個數,就是乙個經典的線段樹合併的題了。
但是現在的問題是他問的是不同的權值個數,這個權值應該怎麼維護呢?現在的問題有兩個,第乙個是如果子樹內有多個相同的權值的話,怎麼防止算重;第二個是相同權值的話,顯然我們只要判斷深度最小的那乙個有沒有被包含就行了,那麼怎麼維護相同顏色在字數內出現的最淺深度。
這樣這個題就做完了,複雜度是o(n
logn
)o(nlogn)
o(nlog
n)。**:
#include
using
namespace std;
int t,n,m,hed[
100010
],cnt,fa[
100010
],num,num1,ans;
int root[
8000010
],root1[
4000010
],val[
100010
],dep[
100010];
struct edge
a[200010];
struct node
tr[8000010];
struct tree
tr1[
4000010];
inline
intread()
return x;
}inline
void
add(
int from,
int to)
inline
void
update
(int
&rt,
int l,
int r,
int x,
int y)
inline
void
update1
(int
&rt,
int l,
int r,
int x,
int y)
if(l==r)
int mid=
(l+r)
>>1;
if(x<=mid)
update1
(tr1[rt]
.l,l,mid,x,y)
;else
update1
(tr1[rt]
.r,mid+
1,r,x,y);}
inline
void
merge
(int
&rt,
int l,
int r)
rt=++num;
tr[rt]
.sz=tr[l]
.sz+tr[r]
.sz;
merge
(tr[rt]
.l,tr[l]
.l,tr[r]
.l);
merge
(tr[rt]
.r,tr[l]
.r,tr[r]
.r);
}inline
intquery
(int rt,
int l,
int r,
int le,
int ri)
inline
void
merge1
(int
&rt,
int l,
int r,
int le,
int ri,
int x)
int ji=rt;
rt=++num1;
tr1[rt]
.l=tr1[ji]
.l; tr1[rt]
.r=tr1[ji]
.r; tr1[rt]
.mn=tr1[ji]
.mn;
if(le==ri)
int mid=
(le+ri)
>>1;
merge1
(tr1[rt]
.l,tr1[l]
.l,tr1[r]
.l,le,mid,x)
;merge1
(tr1[rt]
.r,tr1[l]
.r,tr1[r]
.r,mid+
1,ri,x);}
inline
void
dfs(
int x)
}int
main()
for(
int i=
1;i<=num1;
++i)
for(
int i=
1;i<=cnt;
++i)
num=0;
num1=0;
cnt=0;
ans=0;
n=read()
; m=
read()
;for
(int i=
1;i<=n;
++i)
val[i]
=read()
;for
(int i=
2;i<=n;
++i)
dep[1]
=1;dfs(1
);for(
int i=
1;i<=m;
++i)
}return0;
}
主席樹 BZOJ 4771 七彩樹
感謝帶我飛的rxd大爺 我們先考慮不管深度限制可修改我們怎麼做 就是把每種顏色按照dfs序排列 然後給這些點都 1 但是相鄰兩個的lca處要 1 這樣子樹不同顏色數就是子樹和 然後我們把深度限制 看做按照深度的順序加點 加點我們需要維護什麼 每種顏色的序列 這個用set或平衡樹 在序列中插入 我們對...
BZOJ4771 七彩樹(主席樹)
點此看題面 考慮乙個子樹內所有點 dfs 序是連續的,所以我們可以將其轉化為序列然後用線段樹維護。又由於有深度限制,所以可以對不同深度建不同版本,使用主席樹。但是,本質不同顏色應該如何維護?考慮對於每一種顏色,如果有兩個該顏色的點同時出現,則相當於將這兩個點的權值分別加 1 而把它們 lca 的權值...
七彩樹 HYSBZ 4771線段樹合併
本題是查詢乙個節點x的字樹內深度與其相差不超過d的節點有多少種顏色。如果單純考慮有多少個點,應該如何求?此時我們應該考慮如何維護深度在乙個區間內且是x的後代的資訊。我們可以每個節點用一顆以下標為權值的線段樹來維護 後面記為線段樹x 用線段樹合併來完成所有資訊的處理。但如何查詢深度在乙個區間裡的資訊呢...