ZJOI 2008 樹的統計

2021-08-08 02:51:19 字數 2590 閱讀 3719

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。

我們將以下面的形式來要求你對這棵樹完成一些操作:

i. change u t : 把結點u的權值改為t

ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值

iii. 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」的形式給出。

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

輸入樣例#1:

4

1 22 3

4 14 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 4

輸出樣例#1:

412

21065

6516

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

這是一題明擺著的樹剖題,

我們只需要用線段樹維護兩個資訊,

最大值和總和,

樹剖就是,

路經查詢,單點修改

#include #include #include #include #include using namespace std;

const int maxn = 100000 + 10;

int cnt = 0,map[maxn],val[maxn],num[maxn],size[maxn],father[maxn],son[maxn],top[maxn],dep[maxn],w[maxn];

int n,m,r,p;

vectoredges[maxn];

inline void dfs1(int now,int f)

}inline void dfs2(int now,int ntop)

struct seg tree[maxn*4];

inline void pushup(int root)

inline void buildtree(int l,int r,int root)

int mid = l+r>>1;

buildtree(l,mid,root<<1);

buildtree(mid+1,r,root<<1|1);

pushup(root);

}inline void update(int l,int r,int num,int root,int x)

int mid = l+r>>1;

if (num <= mid) update(l,mid,num,root<<1,x);

else update(mid+1,r,num,root<<1|1,x);

pushup(root);

}inline int querysum(int l,int r,int ql,int qr,int root)

inline int querymax(int l,int r,int ql,int qr,int root)

inline int querysumedges(int u,int v)

sum += querysum(1,cnt,num[topu],num[u],1);

u = father[topu];

topu = top[u];

}if (dep[u] > dep[v]) swap(u,v);

return sum+querysum(1,cnt,num[u],num[v],1);

}inline int querymaxedges(int u,int v)

max = max(max,querymax(1,cnt,num[topu],num[u],1));

u = father[topu];

topu = top[u];

}if (dep[u] > dep[v]) swap(u,v);

return max(max,querymax(1,cnt,num[u],num[v],1));

}int main()

for (int i = 1;i <= n;i++) cin >> val[i];

dfs1(1,0);

dfs2(1,1);

buildtree(1,cnt,1);

cin >> m;

while (m--)

return 0;

}

ZJOI2008 樹的統計

zjoi2008 樹的統計 題目描述 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到...

ZJOI2008 樹的統計

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...

ZJOI2008 樹的統計

題目描述 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 ...