记录编号 |
284279 |
评测结果 |
AAAAAAAAAAAAAAAAAA |
题目名称 |
遥远的国度 |
最终得分 |
100 |
用户昵称 |
Sky_miner |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
3.033 s |
提交时间 |
2016-07-17 16:42:48 |
内存使用 |
15.05 MiB |
显示代码纯文本
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100000 + 10 ;
const int inf = ~0U>>1;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');
if( ch == '-' ) flag = true,ch=getchar();
while(x=10*x+ch-'0',ch=getchar(),ch>'!');
if( flag ) x=-x;
}
inline int cat_min(const int &a,const int &b){
return a<b ? a:b;
}
inline int cat_max(const int &a,const int &b){
return a>b ? a:b;
}
struct Edge{
int to,next;
}G[maxn<<1];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
int n,m,root;
int T[maxn<<2],cov[maxn<<2];
int a[maxn],left[maxn],right[maxn],son[maxn];
int deep[maxn],pos[maxn],fa[maxn][20],size[maxn],top[maxn],tim;
#define v G[i].to
inline void dfs1(int x){
size[x]=1;son[x]=0;
for(int i = head[x];i;i = G[i].next){
if(v != fa[x][0]) {
fa[v][0] = x;
deep[v] = deep[x] + 1;
dfs1(v);
size[x] += size[v];
if(size[v] > size[son[x]]) son[x] = v;
}
}
}
inline void dfs2(int x,int tp){
left[x] = ++tim;
top[x] = tp;
pos[tim] = x;
if(son[x]) dfs2(son[x],tp);
for(int i = head[x];i;i = G[i].next)
if(v != fa[x][0] && v != son[x]) dfs2(v,v);
right[x] = tim;
}
#undef v
inline void build(int rt,int l,int r){
cov[rt] = -1;
if(l == r){
T[rt] = a[pos[l]];
cov[rt] = -1;
return;
}
int mid = l+r >> 1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
T[rt] = cat_min(T[rt<<1],T[rt<<1|1]);
}
inline void pushdown(int rt){
if(cov[rt] != -1){
T[rt<<1] = T[rt<<1|1] = cov[rt<<1] = cov[rt<<1|1] = cov[rt];
cov[rt] = -1;
}
}
int Qx,Qy,ans;
inline void change(int rt,int l,int r,int v){
if(Qx <= l && r <= Qy){
T[rt] = v;
cov[rt] = v;
return;
}
pushdown(rt);
int mid = l+r >> 1;
if(Qx <= mid) change(rt<<1,l,mid,v);
if(Qy > mid) change(rt<<1|1,mid+1,r,v);
T[rt] = cat_min(T[rt<<1],T[rt<<1|1]);
}
inline void query(int rt,int l,int r){
if(Qx > Qy){
ans = inf;
return;
}
if(Qx <= l && r <= Qy){
ans = cat_min(ans,T[rt]);
return ;
}
pushdown(rt);
int mid = l+r >> 1;
if(Qx <= mid) query(rt<<1,l ,mid);
if(Qy > mid) query(rt<<1|1,mid+1,r);
T[rt] = cat_min(T[rt<<1],T[rt<<1|1]);
}
inline int query(int x,int y) {ans = inf;Qx = x;Qy = y;query(1,1,n); return ans;}
inline void change(int x,int y,int v) {Qx = x; Qy = y; change(1,1,n,v);}
inline void init(){
for(int j = 1;j <= 19;++ j)
for(int i = 1;i <= n;++ i)
fa[i][j] = fa[fa[i][j-1]][j-1];
}
inline void fix(int x,int y,int v){
int fx = top[x],fy = top[y];
while(fx != fy) {
if(deep[fx] < deep[fy]) {swap(x,y); swap(fx,fy);}
change(left[fx],left[x],v);
x = fa[fx][0]; fx = top[x];
}
if(deep[x] > deep[y]) swap(x,y);
change(left[x],left[y],v);
}
int main(){
freopen("bbbbb.in","r",stdin);
freopen("bbbbb.out","w",stdout);
read(n);read(m);
int u,v,w;
for(int i = 1;i < n;++ i){
read(u);read(v);
add(u,v); add(v,u);
}
for(int i = 1;i <= n;++i) read(a[i]);
read(root);
dfs1(root);
dfs2(root,root);
init();
build(1,1,n);
int op;
while(m --){
read(op);
if(op == 1) read(u),root = u;
else{
if(op == 2){
read(u); read(v); read(w);
fix(u,v,w);
}else{
read(u);
if(root == u) printf("%d\n",query(1,n));
else{
if(left[u] <= left[root] && right[root] <= right[u]){
int y = root,d = deep[y] - deep[u] - 1;
for(int i = 0;i <= 19;++i)
if(d & (1 << i)) y=fa[y][i];
printf("%d\n",cat_min(query(1,left[y]-1),query(right[y]+1,n)));
}else printf("%d\n",query(left[u],right[u]));
}
}
}
}
return 0;
}