由于边权互不相同,只需用lct维护带加边的最大生成树
#include<bits/stdc++.h> #define lc ch][0 #define rc ch][1 #define fa ch][2 #define rv ch][3 #define val ch][4 #define mv ch][5 #define len ch][6 #define sl ch][7 const int N=400007; int ch[N][8],stk[N]; int _(){ int x=0,c=getchar(); while(c<48)c=getchar(); while(c>47)x=x*10+c-48,c=getchar(); return x; } int min(int a,int b){return a<b?a:b;} int wc(int x){return x!=x[fa][lc];} bool nrt(int x){return x==x[fa][lc]||x==x[fa][rc];} void up(int x){ int l=x[lc],r=x[rc]; x[mv]=min(x[val],min(l[mv],r[mv])); x[sl]=x[len]+l[sl]+r[sl]; } void _rv(int x){ if(x)x[rv]^=1,std::swap(x[lc],x[rc]); } void dn(int x){ if(x[rv]){ x[rv]=0; _rv(x[lc]); _rv(x[rc]); } } void rot(int x){ int f=x[fa],g=f[fa],d=wc(x); if(nrt(f))g[ch][wc(f)]=x; x[fa]=g; (f[ch][d]=x[ch][d^1])[fa]=f; (x[ch][d^1]=f)[fa]=x; up(f); } void sp(int x,int z=0){ int stp=0; for(int a=x;nrt(stk[++stp]=a);a=a[fa]); for(;stp;dn(stk[stp--])); while(nrt(x)&&x[fa]!=z){ int f=x[fa]; if(nrt(f)&&f[fa]!=z)rot(wc(x)==wc(f)?f:x); rot(x); } up(x); } void acs(int x){ int x0=x,y=0; for(;x;sp(x),x[rc]=y,up(y=x),x=x[fa]); sp(x0); } void mrt(int x){ acs(x),_rv(x); } void get(int x,int y){ mrt(x),acs(y),sp(x,y); } int n,m; int main(){ n=_(); for(int i=0;i<=n;++i)i[val]=i[mv]=0x3f3f3f3f; for(m=_();m;--m){ int o=_(); if(o==60372){ int id=_()+n+1,x=_()+1,y=_()+1,t=_(),l=_(); get(x,y); id[val]=t,id[len]=l,up(id); if(x[fa]!=y)x[fa]=id,id[fa]=y; else if(x[rc][mv]<t){ int z=x[rc],tg=x[rc][mv]; for(;z[val]!=tg;dn(z),z=z[ch][z[lc][mv]!=tg]); sp(z); z[lc][fa]=z[rc][fa]=0,z[lc]=z[rc]=0,up(z); mrt(x),x[fa]=id,id[fa]=y; } }else if(o==68053){ int x=_()+1,y=_()+1; printf("%d ",x==y?0:(get(x,y),x[fa]!=y?-1:x[rc][sl])); }else{ int id=_()+n+1,l=_(); sp(id),id[len]=l,up(id); } } return 0; }