板子题,注意链剖基本写法:
sz【o】=1
a<=l&&r<=b
op=2
码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define zuo o<<1,l,mid
#define you o<<1|1,mid+1,r
#define N 30005
int tot,n,q,hou[N<<1],fu[N],xia[N],zhong[N<<1],sum[N<<2],maxx[N<<2],a,b,c,sz[N],dui[N],top[N],hson[N],d[N],op,i;
char str[99];
void jia(int a,int b)
{
++tot;hou[tot]=xia[a];xia[a]=tot;zhong[tot]=b;
}
void jian(int a,int b)
{
jia(a,b);
jia(b,a);
}
void dfs1(int o,int fa,int dis)
{
fu[o]=fa;
d[o]=dis;
sz[o]=1;
int i;
for(i=xia[o];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(nd==fa)continue;
dfs1(nd,o,dis+1);
if(sz[nd]>sz[hson[o]])hson[o]=nd;
sz[o]+=sz[nd];
}
}
void dfs2(int o,int tap)
{
int i,nd;
top[o]=tap;
dui[o]=++tot;
if(hson[o])dfs2(hson[o],tap);
for(i=xia[o];i!=-1;i=hou[i])
{
nd=zhong[i];
if(nd==hson[o]||nd==fu[o])continue;
dfs2(nd,nd);
}
}
void up(int o)
{
sum[o]=sum[o<<1]+sum[o<<1|1];
maxx[o]=max(maxx[o<<1],maxx[o<<1|1]);
}
void gai(int o,int l,int r)
{
if(a<=l&&r<=b)
{
if(op==0)
{
sum[o]=maxx[o]=c;
}
if(op==1)
{
c+=sum[o];
}
if(op==2)
{
c=max(maxx[o],c);
}
return ;
}
int mid=(l+r)>>1;
if(a<=mid)gai(zuo);
if(b>mid)gai(you);
up(o);
}
int work(int x,int y)
{
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])swap(x,y);
a=dui[top[x]];
b=dui[x];
gai(1,1,n);
x=fu[top[x]];
}
if(d[x]<d[y])swap(x,y);
a=dui[y];
b=dui[x];
gai(1,1,n);
return c;
}
int main()
{
scanf("%d",&n);
memset(xia,-1,sizeof(xia));
for(i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
jian(a,b);
}
tot=0;
dfs1(1,0,0);
dfs2(1,1);
for(i=1;i<=n;i++)
{
//cout<<top[i]<<" ";
scanf("%d",&c);
a=b=dui[i];
gai(1,1,n);
}
scanf("%d",&q);
while(q--)
{
scanf("%s",str);
scanf("%d%d",&a,&b);
if(str[1]=='M')
{
c=-99999;op=2;printf("%d\n",work(a,b));
}
if(str[1]=='S')
{
c=0; op=1;printf("%d\n",work(a,b));
}
if(str[0]=='C')
{op=0;
c=b;
a=b=dui[a];
gai(1,1,n);
}
}
}