记录编号 455890 评测结果 AAAAAAAAAAAAAAAAAA
题目名称 遥远的国度 最终得分 100
用户昵称 GravatarLadyLex 是否通过 通过
代码语言 C++ 运行时间 2.026 s
提交时间 2017-10-03 13:36:15 内存使用 5.65 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100010,inf=0x7fffffff;
inline int min(int a,int b){return a<b?a:b;}
int n,e,adj[N];
struct edge{int zhong,next;}s[N<<1];
inline void add(int qi,int zhong)
	{s[++e].zhong=zhong;s[e].next=adj[qi];adj[qi]=e;}
int a[N],cnt,l[N],r[N],dfn[N],cur_root;
int heavy[N],size[N],top[N],fa[N],deep[N];
inline void dfs1(int rt,int Vater)
{
	fa[rt]=Vater,deep[rt]=deep[Vater]+1,size[rt]=1;
	for(register int i=adj[rt];i;i=s[i].next)
		if(s[i].zhong!=Vater)
		{
			dfs1(s[i].zhong,rt),size[rt]+=size[s[i].zhong];
			if(size[s[i].zhong]>size[heavy[rt]])
				heavy[rt]=s[i].zhong;
		}
}
inline void dfs2(int rt,int tp)
{
	l[rt]=++cnt,dfn[cnt]=rt,top[rt]=tp;
	if(heavy[rt])dfs2(heavy[rt],tp);
	for(register int i=adj[rt];i;i=s[i].next)
		if(s[i].zhong!=fa[rt]&&s[i].zhong!=heavy[rt])
			dfs2(s[i].zhong,s[i].zhong);
	r[rt]=cnt;
}
inline int Lca(int a,int b)
{
	while(top[a]!=top[b])
	{
		if(deep[top[a]]<deep[top[b]])a^=b,b^=a,a^=b;
		a=fa[top[a]];
	}
	return deep[a]>deep[b]?b:a;
}
struct node
{
	node *ch[2];int minn,mark;
	node(){minn=inf,mark=-1;}
	inline void update()
		{minn=min(ch[0]->minn,ch[1]->minn);}
}*null=new node(),*root;
inline void pushdown(node *&o)
{
	if(o->mark!=-1)
	{
		if(o->ch[0]!=null)o->ch[0]->minn=o->ch[0]->mark=o->mark;
		if(o->ch[1]!=null)o->ch[1]->minn=o->ch[1]->mark=o->mark;
		o->mark=-1;
	}
}
inline node* newnode()
{
	node *o=new node();
	o->ch[0]=o->ch[1]=null;
	return o;
}
inline node* build(int l,int r)
{
	node *ret=newnode();int mi=l+r>>1;
	if(l==r)ret->minn=a[dfn[l]];
	else
		ret->ch[0]=build(l,mi),
		ret->ch[1]=build(mi+1,r),
		ret->update();
	return ret;
}
inline void set(node *&o,int l,int r,int L,int R,int val)
{
	if(L<=l&&r<=R){o->mark=o->minn=val;return;}
	int mi=l+r>>1;pushdown(o);
	if(L<=mi)set(o->ch[0],l,mi,L,R,val);
	if(mi<R)set(o->ch[1],mi+1,r,L,R,val);
	o->update();
}
inline void set(int a,int b,int val)
{
	while(top[a]!=top[b])
	{
		if(deep[top[a]]<deep[top[b]])a^=b,b^=a,a^=b;
		set(root,1,n,l[top[a]],l[a],val);
		a=fa[top[a]];
	}
	if(deep[a]<deep[b])a^=b,b^=a,a^=b;
	set(root,1,n,l[b],l[a],val);
}
inline int query(node *&o,int l,int r,int L,int R)
{
	if(l>r)return inf;
	if(L<=l&&r<=R)return o->minn;
	pushdown(o);
	register int ret=inf,mi=l+r>>1;
	if(L<=mi)ret=min(ret,query(o->ch[0],l,mi,L,R));
	if(mi<R)ret=min(ret,query(o->ch[1],mi+1,r,L,R));
	return ret;
}
inline int Vater(int rt,int a)
{
	if(top[a]==top[rt])return heavy[rt];
	int ans;
	while(top[a]!=top[rt])
		ans=top[a],a=fa[top[a]];
	return (a==rt)?ans:heavy[rt];
}
inline int query(int rt)
{
	if(rt==cur_root)return root->minn;
	int lca=Lca(rt,cur_root);
	if(lca==rt)
	{
		lca=Vater(rt,cur_root);
		return min(query(root,1,n,1,l[lca]-1),
			query(root,1,n,r[lca]+1,n));
	}
	else return query(root,1,n,l[rt],r[rt]);
}
//      fc bbbbb9.ans bbbbb.out
int main()
{
	freopen("bbbbb.in","r",stdin);
	freopen("bbbbb.out","w",stdout);
	// freopen("Ark.in","r",stdin);
	// freopen("Royal.out","w",stdout);
	register int i,j,m,u,v,x,opt;
	scanf("%d%d",&n,&m);
	for(i=1;i<n;++i)
		scanf("%d%d",&u,&v),add(u,v),add(v,u);
	for(i=1;i<=n;++i)scanf("%d",&a[i]);
	scanf("%d",&cur_root);
	dfs1(cur_root,0),dfs2(cur_root,cur_root);
	null->ch[0]=null->ch[1]=null;
	root=build(1,n);
	while(m--)
	{
		scanf("%d",&opt);
		switch(opt)
		{
			case 1:scanf("%d",&cur_root);break;
			case 2:scanf("%d%d%d",&u,&v,&x),set(u,v,x);break;
			case 3:scanf("%d",&u),printf("%d\n",query(u));break;
		}
	}
}