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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

遥远的国度

發布時間:2025/7/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 遥远的国度 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

zcwwzdjn在追殺十分sb的zhx,而zhx逃入了一個遙遠的國度。當zcwwzdjn準備進入遙遠的國度繼續追殺時,守護神RapiD阻攔了zcwwzdjn的去路,他需要zcwwzdjn完成任務后才能進入遙遠的國度繼續追殺。

問題是這樣的:遙遠的國度有n個城市,這些城市之間由一些路連接且這些城市構成了一顆樹。這個國度有一個首都,我們可以把這個首都看做整棵樹的根,但遙遠的國度比較奇怪,首都是隨時有可能變為另外一個城市的。遙遠的國度的每個城市有一個防御值,有些時候RapiD會使得某兩個城市之間的路徑上的所有城市的防御值都變為某個值。

RapiD想知道在某個時候,如果把首都看做整棵樹的根的話,那么以某個城市為根的子樹的所有城市的防御值最小是多少。

由于RapiD無法解決這個問題,所以他攔住了zcwwzdjn希望他能幫忙。但zcwwzdjn還要追殺sb的zhx,所以這個重大的問題就被轉交到了你的手上。

輸入輸出格式

輸入格式:

第1行兩個整數n m,代表城市個數和操作數。

第2行至第n行,每行兩個整數 u v,代表城市u和城市v之間有一條路。

第n+1行,有n個整數,代表所有點的初始防御值。

第n+2行一個整數 id,代表初始的首都為id。

第n+3行至第n+m+2行,首先有一個整數opt,如果opt=1,接下來有一個整數id,代表把首都修改為id;如果opt=2,接下來有三個整數p1 p2 v,代表將p1 p2路徑上的所有城市的防御值修改為v;如果opt=3,接下來有一個整數 id,代表詢問以城市id為根的子樹中的最小防御值。

輸出格式:

對于每個opt=3的操作,輸出一行代表對應子樹的最小點權值。

輸入輸出樣例

輸入樣例#1:

3 7
1 2
1 3
1 2 3
1
3 1
2 1 1 6
3 1
2 2 2 5
3 1
2 3 3 4
3 1

輸出樣例#1:

1
2
3
4

說明

對于20%的數據,n<=1000 m<=1000。

對于另外10%的數據,n<=100000,m<=100000,保證修改為單點修改。

對于另外10%的數據,n<=100000,m<=100000,保證樹為一條鏈。

對于另外10%的數據,n<=100000,m<=100000,沒有修改首都的操作。

對于100%的數據,n<=100000,m<=100000,0<所有權值<=2^31。

好像除了換根操作之外就是板子

換根 : 我們分3種情況討論
1 . 如果now 和 root 重合 ,那就是查詢整棵樹 ,直接輸出tmin[1]就好了

2 . 如果LCA(now,root) != now 這時根與now沒有關系,直接查詢now的子樹即可

3 . 如果LCA(now,root) = now

這時就比較麻煩了

我們可以先找一下now的所有兒子

由于 一個子樹的dfs序是連續的
所以 如果這個兒子的id大于等于root

并且這個子樹中的最大dfs序(id[son]+size[son]-1)小于等于當前的root

那么就可以判斷出root在這個兒子中或者就是這個兒子,記錄下這個兒子

還是那句話 :一個子樹的dfs序是連續的

這時now的子樹就是去除包含root的那個兒子的子樹的整棵樹了

#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> # define ls now<<1 # define rs now<<1|1 const int M = 100005 ; const int inf = 2100000000 ; using namespace std; inline int read(){char c=getchar(); int x=0,w=1;while(c>'9'||c<'0'){if(c=='-') w=-1 ;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}return x*w; } int n,m; struct E{int nex,to; }edge[M<<1]; int hea[M],num; inline void add_edge(int from,int to){edge[++num].nex=hea[from];edge[num].to=to;hea[from]=num; } int fa[M],dep[M],size[M],son[M]; int val[M],root; void dfs1(int u,int father,int deep){dep[u]=deep; fa[u]=father;size[u]=1 ;int Maxson=-1;for(int i=hea[u];i;i=edge[i].nex){int v=edge[i].to;if(v==father) continue ;dfs1(v,u,deep+1);size[u]+=size[v];if(size[v]>Maxson){Maxson=size[v];son[u]=v;}} } int id[M],cnt,top[M],p[M]; void dfs2(int u,int topf){top[u]=topf; id[u]=++cnt;p[cnt]=val[u];if(!son[u]) return ;dfs2(son[u],topf);for(int i=hea[u];i;i=edge[i].nex){int v=edge[i].to;if(!id[v])dfs2(v,v);} } inline int LCA(int x,int y){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);x=fa[top[x]];}return dep[x]<=dep[y]?x:y; } int tmin[M<<2],tag[M<<2]; inline void pushup(int now){tmin[now]=min(tmin[ls],tmin[rs]); } inline void pushdown(int now){if(tag[now]!=-1){tmin[ls]=tmin[rs]=tag[now];tag[ls]=tag[rs]=tag[now];tag[now]=-1;} } void Build(int l,int r,int now){tag[now]=-1;if(l==r){tmin[now]=p[l];return ;}int mid=(l+r)>>1;Build(l,mid,ls);Build(mid+1,r,rs);pushup(now); } void change(int L,int R,int C,int l,int r,int now){if(l==L&&r==R){tmin[now]=C;tag[now]=C;return ;}int mid=(l+r)>>1;pushdown(now);if(mid>=R) change(L,R,C,l,mid,ls);else if(mid<L) change(L,R,C,mid+1,r,rs);else{change(L,mid,C,l,mid,ls);change(mid+1,R,C,mid+1,r,rs);}pushup(now); } void change1(int x,int y,int C){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);change(id[top[x]],id[x],C,1,n,1);x=fa[top[x]];}if(dep[x]>dep[y]) swap(x,y);change(id[x],id[y],C,1,n,1); } int query(int L,int R,int l,int r,int now){if(l>R||r<L) return inf;if(l>=L&&r<=R) return tmin[now];int mid=(l+r)>>1;pushdown(now);int Ans=query(L,R,l,mid,ls);Ans=min(Ans,query(L,R,mid+1,r,rs));return Ans; } int main(){n=read(); m=read();int u,v;for(int i=1;i<n;i++){u=read(); v=read();add_edge(u,v);add_edge(v,u);}for(int i=1;i<=n;i++) val[i]=read();root=read();dfs1(1,1,1);dfs2(1,1);Build(1,n,1);while(m--){int opt=read();if(opt==1){int x=read();root=x;}else if(opt==2){int u=read(),v=read(),w=read();change1(u,v,w);}else{int x=read();if(x==root) printf("%d\n",tmin[1]);else{int lca=LCA(x,root);if(lca==x){int y;for(int i=hea[x];i;i=edge[i].nex){int v=edge[i].to;if(id[v]<=id[root]&&id[v]+size[v]-1>=id[root]){y=v;break;}}int Ans=query(1,id[y]-1,1,n,1);Ans=min(Ans,query(id[y]+size[y],n,1,n,1));printf("%d\n",Ans);}else printf("%d\n",query(id[x],id[x]+size[x]-1,1,n,1));}}}return 0; }

轉載于:https://www.cnblogs.com/beretty/p/9478685.html

總結

以上是生活随笔為你收集整理的遥远的国度的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。