如果不考虑链翻转,剩余操作都可以用LCT轻松维护
考虑链翻转,我们之所以不能直接再LCT上链翻转,是因为LCT的splay中序遍历还担负着维护深度信息的任务,而我们可以让LCT的splay只维护深度信息,对LCT中的每一个splay T,我们再开一个splay T',同样是以深度有序,维护T中的点的权值,在access操作过程中同时把T'进行与T相同的操作
为了找到与T对应的T',我们在结构splay上维护染色,每个结构splay都染色成其对应的权值splay中的一个点,在access过程中维护染色
然后所有与权值有关的操作都在权值splay中进行,这样的话翻转操作不会更改结构信息
这样做并不破坏复杂度,复杂度仍然是n log n 的(虽然说splay本来常数就大LCT常数更大再这样常数就飞起了-_-)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 100010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
ll mx[MAXN],mn[MAXN],v[MAXN],ch[MAXN],s[MAXN];
int rt[MAXN],cr[MAXN];
int st[MAXN],tp;
struct Splay{
int fa[MAXN],son[MAXN][2];
int siz[MAXN];
bool rev[MAXN];
bool c;
inline void torev(int x){
if(!x){
return ;
}
rev[x]^=1;
swap(son[x][0],son[x][1]);
}
inline void toch(int x,ll y){
if(!x){
return ;
}
v[x]+=y;
mn[x]+=y;
mx[x]+=y;
s[x]+=(ll)siz[x]*y;
ch[x]+=y;
}
inline void tocr(int x,int y){
if(!x){
return ;
}
rt[x]=cr[x]=y;
}
inline void ud(int x){
siz[x]=1+siz[son[x][0]]+siz[son[x][1]];
if(c){
s[x]=v[x]+s[son[x][0]]+s[son[x][1]];
mn[x]=mx[x]=v[x];
if(son[x][0]){
mn[x]=min(mn[x],mn[son[x][0]]);
mx[x]=max(mx[x],mx[son[x][0]]);
}
if(son[x][1]){
mn[x]=min(mn[x],mn[son[x][1]]);
mx[x]=max(mx[x],mx[son[x][1]]);
}
}
}
inline void pd(int x){
if(rev[x]){
torev(son[x][0]);
torev(son[x][1]);
rev[x]=0;
}
if(c){
if(ch[x]){
toch(son[x][0],ch[x]);
toch(son[x][1],ch[x]);
ch[x]=0;
}
}else{
if(cr[x]){
tocr(son[x][0],cr[x]);
tocr(son[x][1],cr[x]);
cr[x]=0;
}
}
}
inline bool ir(int x){
return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
}
inline void cot(int x,int y,bool z){
if(x){
fa[x]=y;
}
if(y){
son[y][z]=x;
}
}
inline void rot(int x,bool z){
int xx=fa[x],xxx=fa[xx];
cot(son[x][z],xx,z^1);
if(ir(xx)){
fa[x]=xxx;
}else{
cot(x,xxx,son[xxx][1]==xx);
}
cot(xx,x,z);
ud(xx);
}
inline void apd(int x){
int i;
st[++tp]=x;
for(i=x;!ir(i);i=fa[i]){
st[++tp]=fa[i];
}
for(;tp;tp--){
pd(st[tp]);
}
}
void splay(int x){
apd(x);
while(!ir(x)){
int xx=fa[x],xxx=fa[xx];
if(ir(xx)){
rot(x,son[xx][0]==x);
}else{
bool z=son[xxx][0]==xx;
if(son[xx][z]==x){
rot(x,z^1);
rot(x,z);
}else{
rot(xx,z);
rot(x,z);
}
}
}
ud(x);
}
int find(int x,int y){
pd(x);
if(siz[son[x][0]]+1==y){
splay(x);
return x;
}
if(y<=siz[son[x][0]]){
return find(son[x][0],y);
}else{
return find(son[x][1],y-siz[son[x][0]]-1);
}
}
};
Splay fm,val;
inline void acs(int x){
int t=0;
while(x){
fm.splay(x);
int X=rt[x];
val.splay(X);
X=val.find(X,fm.siz[fm.son[x][0]]+1);
fm.tocr(fm.son[x][1],val.son[X][1]);
fm.son[x][1]=t;
fm.tocr(x,X);
val.fa[val.son[X][1]]=0;
val.son[X][1]=rt[t];
val.fa[rt[t]]=X;
val.ud(X);
fm.ud(x);
t=x;
x=fm.fa[x];
}
}
inline void reboot(int x){
acs(x);
fm.splay(x);
val.splay(rt[x]);
fm.torev(x);
val.torev(rt[x]);
}
inline void link(int x,int y){
reboot(x);
fm.fa[x]=y;
}
int n,m;
void pt(){
int i;
for(i=1;i<=n;i++){
cerr<<fm.son[i][0]<<' '<<fm.son[i][1]<<' '<<fm.fa[i]<<'!'<<rt[i]<<' '<<cr[i]<<'!'<<fm.rev[i]<<endl;
}
for(i=1;i<=n;i++){
cerr<<val.son[i][0]<<' '<<val.son[i][1]<<' '<<val.fa[i]<<'!'<<v[i]<<' '<<s[i]<<' '<<ch[i]<<'!'<<val.rev[i]<<endl;
}
}
inline void get(int x,int y){
reboot(y);
/*
pt();
cerr<<"----"<<endl;
//*/
acs(x);
fm.splay(x);
val.splay(rt[x]);
}
int main(){
val.c=1;
int i,x,y,z;
char o[20];
int tmp;
scanf("%d%d%*d",&n,&m);
for(i=1;i<=n;i++){
v[i]=0;
s[i]=mx[i]=mn[i]=v[i];
rt[i]=i;
fm.siz[i]=val.siz[i]=1;
ch[i]=cr[i]=fm.fa[i]=val.fa[i]=fm.son[i][0]=fm.son[i][1]=val.son[i][0]=val.son[i][1]=fm.rev[i]=val.rev[i]=0;
}
for(i=1;i<n;i++){
scanf("%d%d",&x,&y);
link(x,y);
//pt();
}
scanf("%d",&m);
while(m--){
scanf("%s%d%d",o,&x,&y);
get(x,y);
if(o[0]=='I'){
if(o[2]=='c'){
scanf("%d",&z);
val.toch(rt[x],z);
}
if(o[2]=='v'){
val.torev(rt[x]);
}
}
if(o[0]=='S'){
printf("%lld\n",s[rt[x]]);
}
if(o[0]=='M'){
if(o[1]=='a'){
printf("%lld\n",mx[rt[x]]);
}
if(o[1]=='i'){
printf("%lld\n",mn[rt[x]]);
}
}
//pt();
}
return 0;
}
/*
5 8 1
1 2
2 3
3 4
4 5
Sum 2 4
Increase 3 5 3
Minor 1 4
Sum 4 5
Invert 1 3
Major 1 2
Increase 1 5 2
Sum 1 5
*/