记录编号 |
256223 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HNOI 2016] 网络 |
最终得分 |
100 |
用户昵称 |
一個人的雨 |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
8.745 s |
提交时间 |
2016-04-29 17:06:52 |
内存使用 |
107.12 MiB |
显示代码纯文本
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=500010;
int n,m,tot=1,h[maxn],fa[maxn][20],dep[maxn];
struct edge{int to,next;}G[maxn*10];
struct ques{int u,v,w,id,b,opt,k,lca;}p[maxn];
int s[maxn],flag[maxn],tim=0,cle=0,st[maxn];
int ans[maxn],mx=0,tmp[maxn],en[maxn];
void add_edge(int x,int y){
G[++tot].to=y;G[tot].next=h[x];h[x]=tot;
}
void dfs(int x,int f){
st[x]=++tim;
dep[x]=dep[f]+1;
for (int i=1;i<=18;++i){
if (dep[x]<(1<<i)) break;
fa[x][i]=fa[fa[x][i-1]][i-1];
}
for (int i=h[x];i;i=G[i].next){
int v=G[i].to;
if (v==f) continue;
fa[v][0]=x; dfs(v,x);
}en[x]=tim;
}
int query(int a,int b){
if (dep[a]<dep[b]) swap(a,b);
int t=dep[a]-dep[b];
for (int i=0;i<=18;++i)
if (t&(1<<i)) a=fa[a][i];
if (a==b) return a;
for (int i=18;~i;i--)
if (fa[a][i]!=fa[b][i])
a=fa[a][i],b=fa[b][i];
return fa[a][0];
}
int lowbit(int x){return x&-x;}
void add(int x,int v){
for (int i=x;i<=n;i+=lowbit(i)){
if (flag[i]!=cle) s[i]=0,flag[i]=cle;
s[i]+=v;
}
}
int ask(int x){
int ret=0;
for (int i=x;i>=1;i-=lowbit(i))
if (flag[i]==cle) ret+=s[i];
return ret;
}
bool cmp(const ques &a,const ques &b){
return a.k<b.k||(a.k==b.k&&a.id<b.id);
}
void solve(int L,int R,int l,int r){
int mid=(L+R)>>1;
if (l>r) return;
if (L==R){
for (int i=l;i<=r;++i)
if (p[i].opt==2) ans[p[i].id]=L;
return;
}
++cle; int t=l-1,num=0;
for (int i=l;i<=r;++i){
if (p[i].opt==0){
if (p[i].w>mid){
p[i].k=1; int lca=p[i].lca; num++;
add(st[p[i].u],1); add(st[p[i].v],1);
add(st[lca],-1);
if (fa[lca][0]) add(st[fa[lca][0]],-1);
}else p[i].k=0,t++;
}else if (p[i].opt==1){
if (p[i].w>mid){
p[i].k=1; int lca=p[i].lca; num--;
add(st[p[i].u],-1); add(st[p[i].v],-1);
add(st[lca],1);
if (fa[lca][0]) add(st[fa[lca][0]],1);
}else p[i].k=0,t++;
}else{
int ret=ask(en[p[i].b])-ask(st[p[i].b]-1);
if (ret<num) p[i].k=1;
else p[i].k=0,t++;
}
}
sort(p+l,p+r+1,cmp);
solve(L,mid,l,t);
solve(mid+1,R,t+1,r);
}
int main(){
freopen("network_tenderRun.in","r",stdin);
freopen("network_tenderRun.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<n;++i){
int x,y; scanf("%d%d",&x,&y);
add_edge(x,y); add_edge(y,x);
}
dfs(1,0);
for (int i=1;i<=m;++i){
int opt,x,y,z; p[i].id=i;
scanf("%d",&opt); p[i].opt=opt;
if (!opt){
scanf("%d%d%d",&x,&y,&z);
p[i].u=x; p[i].v=y; p[i].w=z;
p[i].lca=query(p[i].u,p[i].v);
mx=max(mx,z);
}else if (opt==1){
scanf("%d",&x); p[i]=p[x];
p[i].opt=1; p[i].id=i;
}else if (opt==2)scanf("%d",&p[i].b);
tmp[i]=opt;
}
solve(0,mx,1,m);
for (int i=1;i<=m;++i)
if (tmp[i]==2) printf("%d\n",ans[i]==0?-1:ans[i]);
}