日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[bzoj1036][ZJOI2008]树的统计Count

發(fā)布時間:2025/3/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [bzoj1036][ZJOI2008]树的统计Count 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Description

一棵樹上有$n$個節(jié)點,編號分別為$1$到$n$,每個節(jié)點都有一個權(quán)值$w_i$.

有三種操作:

$1.CHANGE\;u\;t$:把結(jié)點$u$的權(quán)值改為$t$;

$2.QMAX\;u\;v$:詢問從點$u$到點$v$的路徑上的節(jié)點的最大權(quán)值;

$3.QSUM\;u\;v$:詢問從點$u$到點$v$的路徑上的節(jié)點的權(quán)值和.

$P.S.$ 從點$u$到點$v$的路徑上的節(jié)點包括$u$和$v$本身.

Input

第$1$行,$1$個整數(shù)$n$,表示節(jié)點的個數(shù).

接下來$n-1$行,每行$2$個整數(shù)$u$和$v$,表示節(jié)點$u$和$v$之間有一條邊相連.

接下來$1$行,每行$n$個整數(shù),第$i$個整數(shù)$w_i$.表示節(jié)點$i$的權(quán)值.

接下來$1$行,$1$個整數(shù)$q$,表示操作的總數(shù).

接下來$q$行,每行$1$個操作,以"$CHANGE\;u\;t$"或者"$QMAX\;u\;v$"或者"$QSUM\;u\;v$"的形式給出.

Output

對于每個"$QMAX$”或者”$QSUM$”的操作,每行輸出$1$個整數(shù)表示要求輸出的結(jié)果.

Sample Input

4
1 2
2 3
4 1
4 2 1 3
12
QMAX 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

Sample Output

4
1
2
2
10
6
5
6
5
16

HINT

$1\;\leq\;n\;\leq\;30000,0\;\leq\;q\;\leq\;200000$.

中途操作中保證每個節(jié)點的權(quán)值$w_i\in[-30000,30000]$.

Solution

樹鏈剖分+線段樹.

不會樹鏈剖分的,戳這->學(xué)習(xí)筆記-樹鏈剖分

#include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 30005 #define M 60005 using namespace std; struct linetree{int l,r,s,m; }lt[M]; struct graph{int nxt,to; }e[M]; char c[10]; int g[N],w[N],ww[N],n,q,u,v,cnt; int f[N],p[N],dep[N],siz[N],son[N],top[N]; /*top[u]:u所在的鏈的頂端節(jié)點,son[u]:u的重兒子*/ inline void addedge(int x,int y){e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y; } inline void dfs1(int u){int m=0;siz[u]=1;for(int i=g[u];i;i=e[i].nxt)if(!dep[e[i].to]){f[e[i].to]=u;dep[e[i].to]=dep[u]+1;dfs1(e[i].to);siz[u]+=siz[e[i].to];if(siz[e[i].to]>m){son[u]=e[i].to;m=siz[e[i].to];}} } inline void dfs2(int u,int tp){top[u]=tp;p[u]=++cnt;ww[cnt]=w[u];if(son[u]) dfs2(son[u],tp);for(int i=g[u];i;i=e[i].nxt){if(e[i].to!=f[u]&&e[i].to!=son[u])dfs2(e[i].to,e[i].to);} } inline void build(int u,int l,int r){lt[u].l=l;lt[u].r=r;if(lt[u].l<lt[u].r){int lef=u<<1,rig=u<<1|1;int mid=(lt[u].l+lt[u].r)>>1;build(lef,l,mid);build(rig,mid+1,r);lt[u].s=lt[lef].s+lt[rig].s;lt[u].m=max(lt[lef].m,lt[rig].m);}else lt[u].s=lt[u].m=ww[lt[u].l]; } inline void cover(int u,int x,int k){if(lt[u].l<lt[u].r){int lef=u<<1,rig=u<<1|1;int mid=(lt[u].l+lt[u].r)>>1;if(x<=mid) cover(lef,x,k);else cover(rig,x,k); lt[u].s=lt[lef].s+lt[rig].s;lt[u].m=max(lt[lef].m,lt[rig].m);}else lt[u].s=lt[u].m=k; } inline int sum(int u,int l,int r){if(lt[u].l>=l&&lt[u].r<=r)return lt[u].s;if(lt[u].l<lt[u].r){int lef=u<<1,rig=u<<1|1,ret=0;int mid=(lt[u].l+lt[u].r)>>1;if(l<=mid) ret+=sum(lef,l,r);if(r>mid) ret+=sum(rig,l,r);return ret;} } inline int qsum(int x,int y){int ret=0;while(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]]){ret+=sum(1,p[top[x]],p[x]);x=f[top[x]];}else{ret+=sum(1,p[top[y]],p[y]);y=f[top[y]];}}if(p[x]>p[y]){int t=x;x=y;y=t;}ret+=sum(1,p[x],p[y]);return ret; } inline int ask(int u,int l,int r){if(lt[u].l>=l&&lt[u].r<=r)return lt[u].m;if(lt[u].l<lt[u].r){int lef=u<<1,rig=u<<1|1,ret=-30000;int mid=(lt[u].l+lt[u].r)>>1;if(l<=mid) ret=max(ret,ask(lef,l,r));if(r>mid) ret=max(ret,ask(rig,l,r));return ret;} } inline int qmax(int x,int y){int ret=-30000;while(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]]){ret=max(ret,ask(1,p[top[x]],p[x]));x=f[top[x]];}else{ret=max(ret,ask(1,p[top[y]],p[y]));y=f[top[y]];}}if(p[x]>p[y]){int t=x;x=y;y=t;}ret=max(ret,ask(1,p[x],p[y]));return ret; } inline void Aireen(){scanf("%d",&n);for(int i=1,x,y;i<n;++i){scanf("%d%d",&x,&y);addedge(x,y);addedge(y,x);}for(int i=1;i<=n;++i)scanf("%d",&w[i]);dep[1]=1;dfs1(1);cnt=0;dfs2(1,1);build(1,1,n);scanf("%d",&q);while(q--){scanf("%s%d%d",c,&u,&v);if(c[1]=='H') cover(1,p[u],v);else if(c[1]=='M') printf("%d\n",qmax(u,v));else printf("%d\n",qsum(u,v));} } int main(){freopen("count.in","r",stdin);freopen("count.out","w",stdout);Aireen();fclose(stdin);fclose(stdout);return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/AireenYe/p/6219169.html

總結(jié)

以上是生活随笔為你收集整理的[bzoj1036][ZJOI2008]树的统计Count的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。