[luogu4114] Qtree1 题解
\(LCT\) 动态维护树上路径最值,典中典了。
时间复杂度 \(O(n\log n)\)。
#include<bits/stdc++.h>
#define fa(x) lct[x].fa
#define fl(x) lct[x].fl
#define mx(x) lct[x].mx
#define val(x) lct[x].val
#define sn(x,i) lct[x].sn[i]
using namespace std;
const int N=20005;
struct node{
int sn[2],fa,fl,mx,val;
}lct[N];int n,tp,st[N];
int check(int x){
return sn(fa(x),0)!=x&&sn(fa(x),1)!=x;
}int chksn(int x){
return sn(fa(x),1)==x;
}void push_up(int x){
mx(x)=max({mx(sn(x,0)),mx(sn(x,1)),val(x)});
}void push_down(int x){
if(!x||!fl(x)) return;
fl(sn(x,0))^=1,fl(sn(x,1))^=1;
swap(sn(x,0),sn(x,1)),fl(x)=0;
}void rotate(int x){
int y=fa(x),z=fa(y),k=chksn(x);
if(!check(y)) sn(z,chksn(y))=x;
fa(x)=z,fa(y)=x,fa(sn(x,1-k))=y;
sn(y,k)=sn(x,1-k),sn(x,1-k)=y;
push_up(y);
}void splay(int x){
st[tp=1]=x;
for(int i=x;!check(i);i=fa(i)) st[++tp]=fa(i);
while(tp) push_down(st[tp--]);
while(!check(x)){
int y=fa(x),z=fa(y);
if(!check(y))
rotate(chksn(x)!=chksn(y)?x:y);
rotate(x);
}push_up(x);
}void access(int x){
for(int i=0;x;i=x,x=fa(x))
splay(x),sn(x,1)=i,push_up(x);
}void mk(int x){
access(x),splay(x),fl(x)^=1;
}void split(int x,int y){
mk(x),access(y),splay(y);
}void cut(int x,int y){
split(x,y),fa(x)=sn(y,0)=0;
}void link(int x,int y){
mk(x),access(y),fa(x)=y;
}int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;string s;
for(int i=1,x,y;i<n;i++){
cin>>x>>y>>mx(n+i);
val(n+i)=mx(n+i);
link(x,n+i),link(n+i,y);
}while(cin>>s){
if(s=="DONE") return 0;
int x,y;cin>>x>>y;
if(s=="CHANGE") mk(x+n),val(x+n)=y;
else split(x,y),cout<<mx(y)<<"\n";
}return 0;
}

浙公网安备 33010602011771号