bzoj3319: 黑白树
卡常卡了老半天。。。(自带大常数的毒瘤选手的痛)
边归到点,先把最后的图处理出来再倒着返回,把白色的边压到一个并查集,答案就是根的父亲
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct node { int x,y,id,next; }a[2100000];int len,last[1100000]; void ins(int x,int y,int id) { len++; a[len].x=x;a[len].y=y;a[len].id=id; a[len].next=last[x];last[x]=len; } int Bin[21],f[21][1100000],dep[1100000]; int LCA(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int i=20;i>=0;i--) if(dep[x]-dep[y]>=Bin[i])x=f[i][x]; if(x==y)return x; for(int i=20;i>=0;i--) if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y]; return f[0][x]; } int id[1100000]; void dfs(int x) { for(int i=1;Bin[i]<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=f[0][x]) { f[0][y]=x; dep[y]=dep[x]+1; id[y]=a[k].id; dfs(y); } } } int fa[2][1100000]; int findfa(int x,int w) { if(fa[w][x]==x)return x; fa[w][x]=findfa(fa[w][x],w);return fa[w][x]; } void merge(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=f[0][x]) { if(fa[0][y]==y)fa[1][y]=findfa(fa[1][x],1); merge(y); } } } int las[1100000],nxt[1100000]; struct query{int op,x,y;}q[1100000]; int as[1100000]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n,Q,x,y; n=read(),Q=read(); len=0;memset(last,0,sizeof(last)); for(int i=1;i<n;i++) { x=read(),y=read(); ins(x,y,i),ins(y,x,i); } Bin[0]=1;for(int i=1;i<=20;i++)Bin[i]=Bin[i-1]*2; dep[1]=0;f[0][1]=0;id[1]=0;dfs(1); int asum=0; for(int i=1;i<=n;i++)fa[0][i]=i; memset(las,0,sizeof(las)); for(int i=1;i<=Q;i++) { q[i].op=read(); if(q[i].op==1)q[i].x=read(),asum++; else { q[i].x=read(),q[i].y=read(); int lca=findfa(LCA(q[i].x,q[i].y),0); int F=findfa(q[i].x,0); while(F!=lca) { int FF=findfa(f[0][fa[0][F]],0); fa[0][F]=lca; nxt[F]=las[i],las[i]=F; F=FF; } F=findfa(q[i].y,0); while(F!=lca) { int FF=findfa(f[0][fa[0][F]],0); fa[0][F]=lca; nxt[F]=las[i],las[i]=F; F=FF; } } } for(int i=1;i<=n;i++)fa[1][i]=i; merge(1); int t=asum; for(int i=Q;i>=1;i--) { if(q[i].op==1)as[t--]=id[findfa(q[i].x,1)]; else { for(int F=las[i];F;F=nxt[F]) fa[1][F]=findfa(f[0][fa[1][F]],1); } } for(int i=1;i<=asum;i++)printf("%d\n",as[i]); return 0; }
pain and happy in the cruel world.