用合并直径的定理,并查集维护每棵树的直径
主要是看看过了这么久自己的lct有没有变残废2333(1A还行
#include<stdio.h> int ch[300010][2],fa[300010],r[300010],siz[300010],sfa[300010],d1[300010],d2[300010]; void pushup(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;} void swap(int&a,int&b){a^=b^=a^=b;} void rev(int x){ r[x]^=1; swap(ch[x][0],ch[x][1]); } void pushdown(int x){ if(r[x]){ if(ch[x][0])rev(ch[x][0]); if(ch[x][1])rev(ch[x][1]); r[x]=0; } } bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} void rot(int x){ int y,z,f,B; y=fa[x]; z=fa[y]; f=(ch[y][0]==x); B=ch[x][f]; fa[x]=z; fa[y]=x; if(B)fa[B]=y; ch[x][f]=y; ch[y][f^1]=B; if(ch[z][0]==y)ch[z][0]=x; if(ch[z][1]==y)ch[z][1]=x; pushup(y); pushup(x); } void gao(int x){ if(fa[x])gao(fa[x]); pushdown(x); } void splay(int x){ gao(x); int y,z; while(!isrt(x)){ y=fa[x]; z=fa[y]; if(!isrt(y))rot((ch[z][0]==y&&ch[y][0]==x)||(ch[z][1]==y&&ch[y][1]==x)?y:x); rot(x); } } void access(int x){ int y=0; while(x){ splay(x); ch[x][1]=y; pushup(x); y=x; x=fa[x]; } } void makert(int x){ access(x); splay(x); rev(x); } void link(int x,int y){ makert(x); fa[x]=y; } int query(int x,int y){ makert(x); access(y); splay(y); return siz[y]-1; } int getfa(int x){return(x==sfa[x])?x:(sfa[x]=getfa(sfa[x]));} int max(int a,int b){return a>b?a:b;} int main(){ int type,n,m,i,j,x,y,mx,p1,p2,las,tmp,t[4]; scanf("%d%d%d",&type,&n,&m); for(i=1;i<=n;i++){ siz[i]=1; sfa[i]=d1[i]=d2[i]=i; } las=0; while(m--){ scanf("%d",&i); if(i==1){ scanf("%d%d",&x,&y); if(type==1){ x^=las; y^=las; } link(x,y); x=getfa(x); y=getfa(y); t[0]=d1[x]; t[1]=d2[x]; t[2]=d1[y]; t[3]=d2[y]; mx=0; for(i=0;i<3;i++){ for(j=i+1;j<4;j++){ tmp=query(t[i],t[j]); if(tmp>mx){ mx=tmp; p1=t[i]; p2=t[j]; } } } d1[x]=p1; d2[x]=p2; sfa[y]=x; }else{ scanf("%d",&x); if(type==1)x^=las; y=getfa(x); las=max(query(x,d1[y]),query(x,d2[y])); printf("%d\n",las); } } }