水题
裸树剖
线段树记录最大值与和。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,num=0,en=0,tn=0,fst[30010],q;
struct edge
{
int x,y,n;
}e[60010];
struct tree
{
int l,r,lc,rc,c1,c2;
}tr[60010];
struct pnt
{
int f,tp,s,dp,sz,en;
}p[30010];
void ins(int x,int y)
{
e[++num]={x,y,fst[x]};
fst[x]=num;
}
void sd1(int x,int f)
{
p[x].f=f;
p[x].sz=1;
p[x].dp=p[f].dp+1;
for(int i=fst[x];i;i=e[i].n)
{
int y=e[i].y;
if(y==f)
continue;
sd1(y,x);
if(p[y].sz>p[p[x].s].sz)
p[x].s=y;
p[x].sz+=p[y].sz;
}
}
void sd2(int x,int tp)
{
p[x].en=++en;
p[x].tp=tp;
if(p[x].s)
{
sd2(p[x].s,tp);
for(int i=fst[x];i;i=e[i].n)
{
int y=e[i].y;
if(y==p[x].s||y==p[x].f)
continue;
sd2(y,y);
}
}
}
int bt(int l,int r)
{
int i=++tn;
tr[i]={l,r,-1,-1,0,0};
if(l<r)
{
int md=l+r>>1;
tr[i].lc=bt(l,md);
tr[i].rc=bt(md+1,r);
}
return i;
}
void chg(int i,int x,int p)
{
if(tr[i].l==tr[i].r)
{
tr[i].c1=tr[i].c2=x;
return;
}
int md=tr[i].l+tr[i].r>>1,lc=tr[i].lc,rc=tr[i].rc;
if(p<=md)
chg(lc,x,p);
else
chg(rc,x,p);
tr[i].c1=tr[lc].c1+tr[rc].c1;
tr[i].c2=max(tr[lc].c2,tr[rc].c2);
}
int get(int i,int l,int r,bool tf)
{
if(tr[i].l==l&&tr[i].r==r)
{
if(tf)
return tr[i].c1;
else
return tr[i].c2;
}
int md=tr[i].l+tr[i].r>>1,lc=tr[i].lc,rc=tr[i].rc;
if(r<=md)
return get(lc,l,r,tf);
else if(l>md)
return get(rc,l,r,tf);
else
{
if(tf)
return get(lc,l,md,tf)+get(rc,md+1,r,tf);
else
return max(get(lc,l,md,tf),get(rc,md+1,r,tf));
}
}
int qr(int x,int y,bool tf)
{
int tx=p[x].tp,ty=p[y].tp,ans;
if(tf)
ans=0;
else
ans=-2147483647;
while(tx!=ty)
{
if(p[tx].dp<p[ty].dp)
{
swap(tx,ty);
swap(x,y);
}
// printf("%d %d\n",tx,x);
int s=get(1,p[tx].en,p[x].en,tf);
if(tf)
ans+=s;
else
ans=max(ans,s);
x=p[tx].f;
tx=p[x].tp;
}
if(p[x].dp>p[y].dp)
swap(x,y);
int s=get(1,p[x].en,p[y].en,tf);
if(tf)
ans+=s;
else
ans=max(ans,s);
return ans;
}
int main()
{
memset(fst,0,sizeof(fst));
memset(p,0,sizeof(p));
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);
ins(y,x);
}
sd1(1,0);
sd2(1,1);
bt(1,en);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
chg(1,x,p[i].en);
}/*
for(int i=1;i<=tn;i++)
printf("%d %d %d %d %d %d\n",tr[i].l,tr[i].r,tr[i].lc,tr[i].rc,tr[i].c1,tr[i].c2);*/
scanf("%d",&q);
for(int i=0;i<q;i++)
{
char s[10];
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[1]=='M')
printf("%d\n",qr(x,y,0));
else if(s[1]=='S')
printf("%d\n",qr(x,y,1));
else
chg(1,y,p[x].en);
}
}