確實是神(mo ban)薙(ti)
好多數據結構都靠這個入門- -
用LCT解這道題也很簡單。
維護val,maxval,sum.
CHANGE的時候把這個點旋到當前splay的根,然後進行操作
QMAX,先把u設爲整棵樹的根,再把v旋到當前splay的根,然後找到當前樹(u-v這條路徑)的根,讀取信息
QSUM,和上面一樣,讀取SUM.
然後就是模板了:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int maxn=30000+20;
const int inf=0x3f3f3f3f;
struct node
{
node *f;
node *ch[2];
int val;
int sum;
int maxval;
bool rev;
}tree[maxn],*null,Tnull;
void init(node *u)
{
u->f=u->ch[0]=u->ch[1]=null;
u->val=u->sum=0;
u->maxval=-inf;
u->rev=0;
}
void pushup(node *u)
{
u->sum=u->val+u->ch[0]->sum+u->ch[1]->sum;
u->maxval=max(u->val,max(u->ch[0]->maxval,u->ch[1]->maxval));
}
void pushdown(node *u)
{
if(u==null)return ;
if(u->rev)
{
swap(u->ch[0],u->ch[1]);
if(u->ch[0]!=null)u->ch[0]->rev^=1;
if(u->ch[1]!=null)u->ch[1]->rev^=1;
u->rev=0;
}
}
bool isroot(node *u)
{
return u==null||u->f->ch[0]!=u&&u->f->ch[1]!=u;
}
void rotate(node *u)
{
node *f=u->f;
node *ff=f->f;
int d=u==f->ch[1];
if(u->ch[d^1]!=null)u->ch[d^1]->f=f;
f->ch[d]=u->ch[d^1];
u->f=ff;
if(ff!=null)
{
if(f==ff->ch[0])ff->ch[0]=u;
else if(f==ff->ch[1])ff->ch[1]=u;
}
u->ch[d^1]=f;
f->f=u;
pushup(f);
pushup(u);
}
int cnt;
node *sta[maxn];
void splay(node *u)
{
if(u==null)return ;
cnt=1;
sta[0]=u;
for(node *y=u;!isroot(y);y=y->f)
{
sta[cnt++]=y->f;
}
while(cnt)pushdown(sta[--cnt]);
while(!isroot(u))
{
node *f=u->f;
if(isroot(f))
{
rotate(u);
}
else
{
node *ff=f->f;
int d=u==f->ch[1];
int dd=f==ff->ch[1];
if(d==dd)rotate(f);
else rotate(u);
rotate(u);
}
}
pushup(u);
}
node *access(node *u)
{
node *v=null;
while(u!=null)
{
splay(u);
u->ch[1]=v;
v->f=u;
pushup(u);
v=u;
u=u->f;
}
return v;
}
int n,m;
int head[maxn];
struct edge
{
int v,next;
}e[2*maxn];
int det[maxn];
int k;
void add(int u,int v)
{
e[k].v=v;
e[k].next=head[u];
head[u]=k++;
}
void dfs(int u,int f)
{
tree[u].val=tree[u].maxval=tree[u].sum=det[u];
if(f!=-1)tree[u].f=tree+f;
else tree[u].f=null;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(v==f)continue;
dfs(v,u);
}
}
void changeroot(node *u)
{
access(u)->rev^=1;
}
char ss[20];
node *getroot(node *u)
{
access(u);
splay(u);
while(u->f!=null)u=u->f;
splay(u);
return u;
}
void QMAX(node *u,node *v)
{
changeroot(u);
access(v);
node *q=getroot(v);
printf("%d\n",q->maxval);
}
void QSUM(node *u,node *v)
{
changeroot(u);
access(v);
node *q=getroot(v);
printf("%d\n",q->sum);
}
void CHANGE(node *u,int v)
{
access(u);
splay(u);
u->val=v;
pushup(u);
}
int main()
{
k=1;
memset(head,-1,sizeof(head));
null=&Tnull;
init(null);
scanf("%d",&n);
for(int i=1;i<=n;i++)init(&tree[i]);
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=1;i<=n;i++)scanf("%d",&det[i]);
dfs(1,-1);
scanf("%d",&m);
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%s%d%d",ss,&u,&v);
if(ss[1]=='M')QMAX(tree+u,tree+v);
else if(ss[1]=='S')QSUM(tree+u,tree+v);
else CHANGE(tree+u,v);
}
return 0;
}