首觸樹鏈剖分

2021-08-01 03:49:02 字數 2528 閱讀 7474

time limit: 10 sec  

memory limit: 162 mb

submit: 16525  

solved: 6719 [

submit][

status][

discuss]

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成

一些操作: i. change u t : 把結點u的權值改為t ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值 i

ii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和 注意:從點u到點v的路徑上的節點包括u和v本身

輸入的第一行為乙個整數n,表示節點的個數。接下來n – 1行,每行2個整數a和b,表示節點a和節點b之間有

一條邊相連。接下來n行,每行乙個整數,第i行的整數wi表示節點i的權值。接下來1行,為乙個整數q,表示操作

的總數。接下來q行,每行乙個操作,以「change u t」或者「qmax u v」或者「qsum u v」的形式給出。 

對於100%的資料,保證1<=n<=30000,0<=q<=200000;中途操作中保證每個節點的權值w在-30000到30000之間。

對於每個「qmax」或者「qsum」的操作,每行輸出乙個整數表示要求輸出的結果。

41 2

2 34 1

4 2 1 3

12qmax 3 4

qmax 3 3

qmax 3 2

qmax 2 3

qsum 3 4

qsum 2 1

change 1 5

qmax 3 4

change 3 6

qmax 3 4

qmax 2 4

qsum 3 441

22106

56516

#include

#include

#include

#include

using namespace std;

#define n 30001

//segment tree

int l[3*n],r[3*n],qsum[3*n],fid[3*n],id[3*n],pos,qmax[3*n];

//shulianpoufen

int fa[n],top[n],size[n],n,m,zson[n],depth[n];

//bianbiao

int fir[n],next[2*n],to[2*n],tot;

int x,y,q,val[n];

//bian go first

void add(int u,int v)

void dfs(int father,int deep,int x)

}void getpos(int x,int sp)

}void build(int ll,int rr,int no)

int le=no*2,ri=le+1;

build(ll,mid,le);build(mid+1,rr,ri);

qsum[no]=qsum[le]+qsum[ri];qmax[no]=max(qmax[le],qmax[ri]);

return;

}int getmax(int ll,int rr,int no)

int getsum(int ll,int rr,int no)

void change(int u,int t,int no)

if(mid>=u) 

change(u,t,no*2);else change(u,t,no*2+1);

int le=no*2,ri=le+1;

qsum[no]=qsum[le]+qsum[ri];

qmax[no]=max(qmax[le],qmax[ri]);

return;

}void init()

for(int i=1;i<=n;i++) scanf("%d",&val[i]);

scanf("%d",&q);

dfs(0,1,1);

getpos(1,1);build(1,pos,1);

}char type[101];

int query_max(int u,int v)

ans=max(ans,getmax(id[f1],id[u],1));

u=fa[f1];f1=top[u];

}if(depth[u]

return ans=max(ans,getmax(id[v],id[u],1));

}int query_sum(int u,int v)

ans+=getsum(id[f1],id[u],1);

u=fa[f1];f1=top[u];

}if(depth[u]

return ans+=getsum(id[v],id[u],1);

}void do_one_move()

else if(strcmp(type,"qsum")==0)

else

}int main()

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

演算法入門 樹鏈剖分 輕重鏈剖分

目錄 3.0 求 lca 4.0 利用資料結構維護資訊 5.0 例題 參考資料 資料結構入門 線段樹 發表於 2019 11 28 20 39 dfkuaid 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...

樹鏈剖分 樹剖換根

這是一道模板題。給定一棵 n 個節點的樹,初始時該樹的根為 1 號節點,每個節點有乙個給定的權值。下面依次進行 m 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙...