记录编号 346693 评测结果 AAAAAAAAAA
题目名称 [HNOI 2016] 网络 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 25.508 s
提交时间 2016-11-12 14:26:44 内存使用 26.91 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=500010;
struct edge{int f,t;}w[N];
int n,m,fa[N],head[N],tail[N],next[N];
void add(int f,int num){
	if (!head[f]) head[f]=tail[f]=num;
		else tail[f]=next[tail[f]]=num;
}
//树剖 
int size[N],dfn[N],h[N],cnt,hash[N],big[N],link[N];
void dfs(int x){
	size[x]=1;
	for (int i=head[x];i;i=next[i])
	if (!fa[w[i].t]){
		fa[w[i].t]=x;
		h[w[i].t]=h[x]+1;
		dfs(w[i].t);
		size[x]+=size[w[i].t];
		if (size[w[i].t]>size[big[x]]) big[x]=w[i].t;
	}
}
void dfs1(int x){
	hash[dfn[x]=++cnt]=x;
	if (dfn[x]==dfn[fa[x]]+1) link[x]=link[fa[x]];
		else link[x]=x;
	if (big[x]) dfs1(big[x]);
	for (int i=head[x];i;i=next[i])
	if (w[i].t!=big[x]&&w[i].t!=fa[x]) dfs1(w[i].t);
}
//维护树剖 
int a[N];
void Add(int p,int d){
	for (;p<=n;p+=(p&-p)) a[p]+=d;
}
int sum(int r){
	int ans=0;
	for (;r;r-=(r&-r)) ans+=a[r];
	return ans;
}
inline void swap(int &x,int &y){int z=x;x=y;y=z;}
inline void add(int x,int y,int d){//一条[x,y]线段,O(log^2n) 
	Add(1,d);
	while (link[x]!=link[y]){
		if (h[link[x]]<h[link[y]]) swap(x,y);
		Add(dfn[link[x]],-d);
		Add(dfn[x]+1,d);
		x=fa[link[x]];
	}
	if (h[x]<h[y]) swap(x,y);
	Add(dfn[y],-d);
	Add(dfn[x]+1,d);
}
//分治 
struct qs{int type,a,b,v,id,k;}q[N];
int ans[N];
inline bool cmp(const qs &x,const qs &y){
	return x.k==y.k?x.id<y.id:x.k<y.k;
}
void solve(int L,int R,int l,int r){//O(logn)
	if (l>r) return;
	if (L==R){
		for (int i=l;i<=r;i++)
		if (q[i].type==2) ans[q[i].id]=L;
		return;
	}
	int M=(L+R)/2,t=l-1;
	for (int i=l;i<=r;i++){
		if (!q[i].type){
			if (q[i].v>M) add(q[i].a,q[i].b,1),q[i].k=1;
				else t++,q[i].k=0;
		}
		if (q[i].type==1){
			if (q[i].v>M) add(q[i].a,q[i].b,-1),q[i].k=1;
				else t++,q[i].k=0;
		}
		if (q[i].type==2){
			int s=sum(dfn[q[i].v]);
			if (s>0) q[i].k=1;//存在大于M的 
				else t++,q[i].k=0;
		}
	}
	for (int i=l;i<=r;i++){
		if (!q[i].type&&q[i].v>M) add(q[i].a,q[i].b,-1);
		if (q[i].type==1&&q[i].v>M) add(q[i].a,q[i].b,1);
	}
	sort(q+l,q+r+1,cmp);
	solve(L,M,l,t);solve(M+1,R,t+1,r);
}
inline int read(){
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
int main()
{
	freopen("network_tenderRun.in","r",stdin);
	freopen("network_tenderRun.out","w",stdout);
	n=read();m=read();
	for (int i=1;i<n;i++){
		w[i].f=read();w[i].t=read();
		w[i+n].t=w[i].f;w[i+n].f=w[i].t;
		add(w[i].f,i);add(w[i].t,i+n);
	}
	fa[1]=h[1]=1;dfs(1);dfs1(1);
	int M=0;
	for (int i=1;i<=m;i++){
		q[i].type=read();
		q[i].id=i;
		if (!q[i].type){
			q[i].a=read();
			q[i].b=read();
			q[i].v=read();
			M=max(M,q[i].v);
		}
		if (q[i].type==1){
			int t=read();
			q[i].a=q[t].a;
			q[i].b=q[t].b;
			q[i].v=q[t].v;
		}
		if (q[i].type==2) q[i].v=read();
	}
	memset(ans,-1,sizeof ans);
	solve(0,M,1,m);
	for (int i=1;i<=m;i++)
	if (ans[i]!=-1) printf("%d\n",ans[i]?ans[i]:-1);
	return 0;
}