bzoj 3730 震波 動態樹分治

2021-09-26 23:49:18 字數 1798 閱讀 9849

給出一棵樹,點有點權,每次詢問距離乙個點不超過k

kk

≤100000

n\le100000

n≤1000

00把點分樹建出來,然後對每個分治中心用樹狀陣列維護到該點距離為定值的點權和,以及到他點分樹上父親距離為定值的點權和。查詢的時候每次沿著父親往上跳,在計算當前點貢獻時需要減去上乙個點所在子樹的貢獻。

時間複雜度o(n

log⁡2n

)o(n\log^2n)

o(nlog2n

)

#include

#include

#include

#include

#include

#include

const

int n=

100005

;int n,m,cnt,last[n]

,dep[n]

,dfn[n]

,top,rmq[n*2]

[20],lg[n*2]

,bin[20]

,c1[20]

[n],c2[20]

[n],fa[n]

,rt,sum,mx[n]

,a[n]

,beg[n]

,size[n]

,dd[n]

,tot[20]

,end[n]

;bool vis[n]

;struct edgee[n*2]

;void

addedge

(int u,

int v)

void

dfs(

int x,

int fa)

void

get_rmq()

intget_dis

(int x,

int y)

void

get_root

(int x,

int fa)

mx[x]

=std:

:max

(mx[x]

,sum-size[x]);

if(!rt||mx[x]

) rt=x;

}void

ins1

(int d,

int x,

int y)

void

ins2

(int d,

int x,

int y)

intquery1

(int d,

int x)

intquery2

(int d,

int x)

void

pre(

int x,

int fa,

int p1,

int p2)

void

solve

(int x)

}int

query

(int x,

int y)

return ans;

}void

modify

(int x,

int y)

}int

main()

dfs(1,

0);get_rmq()

; rt=

0;sum=n;

get_root(1

,0);

solve

(rt)

;int ans=0;

while

(m--

)return0;

}

bzoj3730 震波 動態樹分治

第一行包含兩個正整數n和m。第二行包含n個正整數,第i個數表示value i 接下來n 1行,每行包含兩個正整數u v,表示u和v之間有一條無向邊。接下來m行,每行包含三個數,表示m次操作。包含若干行,對於每個詢問輸出一行乙個正整數表示答案。這道題是動態樹分治的模板題。簡要的思路 先建出分治樹,每次...

BZOJ3730 震波 動態點分治

include include include include include include define space putchar define enter putchar n using namespace std typedef long long ll template void rea...

BZOJ3730 震波 動態點分治

在一片土地上有n個城市,通過n 1條無向邊互相連線,形成一棵樹的結構,相鄰兩個城市的距離為1,其中第i個城市的價值為value i 不幸的是,這片土地常常發生 並且隨著時代的發展,城市的價值也往往會發生變動。0 x k 表示發生了一次 震中城市為x,影響範圍為k,所有與x距離不超過k的城市都將受到影...