bzoj3730 震波 動態樹分治

2022-05-25 15:06:07 字數 2161 閱讀 9668

第一行包含兩個正整數n和m。

第二行包含n個正整數,第i個數表示value[i]。

接下來n-1行,每行包含兩個正整數u、v,表示u和v之間有一條無向邊。

接下來m行,每行包含三個數,表示m次操作。

包含若干行,對於每個詢問輸出一行乙個正整數表示答案。

這道題是動態樹分治的模板題。

簡要的思路:

先建出分治樹,每次修改和查詢都在這個節點在分治樹到根的路徑上的所有祖先上面進行操作。

具體實現:

對每乙個節點開2棵線段樹,儲存分治樹上這個節點子樹的資訊。

第一棵線段樹:以子樹中所有點到這個點的距離為下標,點權為權值,維護區間的和。

第二棵線段樹:以子樹中所有點到這個點的分治樹上的父親的距離為下標,點權為權值,維護區間的和。

修改:在到根的路徑上的所有線段樹中刪除這個點原來的點權,加入新的點權。

查詢:在分治樹上從查詢點往根爬的時候,統計答案。設查詢距離為d1,當前節點的父親到查詢點的距離為d2。答案加上當前節點的父親維護的子樹內第一棵線段樹下標為0~d1-d2的點權總和,再減去當前節點維護的子樹內第二棵線段樹下標為0~d1-d2點權總和,因為從下面爬上來時,當前點的貢獻已經計算過了,需要減掉,不然會重複。

於是就搞定啦!

**:

#include

#include

using

namespace

std;

const

int n=200005;

int n,m,op,u,v,cnt,idx,tot,ans,log2[n*2],a[n],head[n],to[n*2],nxt[n*2],dfn[n],dep[n],siz[n],pos[n*2],f[n*2][25];

int rt,mi,size,fa[n],root[n][2],sumv[n*50],ch[n*50][2],dd[n];

bool vis[n];

void adde(int u,int v)

void dfs(int pre,int u)

}}void st()

for(int j=1;j<=20;j++)else}}

}int lca(int u,int v)

int k=log2[dfn[v]-dfn[u]];

if(dep[f[dfn[u]][k]]1

<1][k]])else

}int dis(int u,int v)

void upd(int &o,int l,int r,int k,int v)

if(!o)

sumv[o]+=v;

if(l==r)

int mid=(l+r)/2;

if(k<=mid)else

}int qry(int o,int l,int r,int l,int r)

if(l==l&&r==r)

int mid=(l+r)/2;

if(r<=mid)else

if(l>mid)else

}void dfsroot(int pre,int u)

}mx=max(mx,size-siz[u]);

if(mxvoid init(int rt,int md,int pre,int u)

}}void dfstree(int u)

}}int query(int u,int d)

return ans;

}void update(int u,int k)

a[u]=k;

}int main()

scanf("%d%d",&n,&m);

for(int i=1;i<=n;i++)

for(int i=1;iscanf("%d%d",&u,&v);

adde(u,v);

adde(v,u);

}dfs(0,1);

st();

size=mi=siz[1];

dfsroot(0,1);

dfstree(rt);

for(int i=1;i<=m;i++)else

}return

0;}

bzoj 3730 震波 動態樹分治

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

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的城市都將受到影...