197 lines
3.5 KiB
C++
197 lines
3.5 KiB
C++
#include<iostream>
|
||
#include<string>
|
||
#include<algorithm>
|
||
#include<cstdio>
|
||
#include<cstring>
|
||
using namespace std;
|
||
const int N=3e4+1,N2=N<<1,inf=0x3f3f3f3f;//N2 双向边记得*2
|
||
int to[N2],h[N2],ne[N2];
|
||
int nid[N],oid[N],top[N],w[N],dep[N],fa[N];
|
||
int siz[N],son[N];//子树节点数,重边儿子(siz最大的儿子)
|
||
int qs[N<<2],qm[N<<2];
|
||
int t,u,v,w1,qu,n,cnt=0,maxson;
|
||
char opt[11];
|
||
|
||
#define ls rt<<1
|
||
#define rs rt<<1|1
|
||
#define mid ((l+r)>>1) //>>1写成>>2
|
||
#define lson ls,l,mid //l写成1
|
||
#define rson rs,mid+1,r
|
||
#define len (r-l+1)
|
||
void add(int u,int v)
|
||
{
|
||
to[++cnt]=v;
|
||
ne[cnt]=h[u];
|
||
h[u]=cnt;
|
||
}
|
||
//以下是线段树
|
||
int tot=0;
|
||
void build(int rt,int l,int r)
|
||
{
|
||
if(l==r)
|
||
{
|
||
qm[rt]=w[oid[l]];
|
||
qs[rt]=w[oid[l]];
|
||
// printf("l:%d,qm[%d]=w[%d]=%d\n",l,rt,oid[l],qm[rt]);
|
||
return;
|
||
}
|
||
// if(rt<=mid)
|
||
build(ls,l,mid);
|
||
// else
|
||
build(rs,mid+1,r);
|
||
qm[rt]=max(qm[ls],qm[rs]);
|
||
qs[rt]=qs[ls]+qs[rs];//bug TLE直接等于两个孩子相加
|
||
// printf("a[%d]=a[%d]%d/a[%d]%d\n",rt,ls,qm[ls],rs,qm[rs]);
|
||
}
|
||
inline int qmax(int rt,int l,int r,int L,int R)
|
||
{
|
||
if(L<=l&&r<=R)
|
||
{
|
||
// printf("[%d]",rt);
|
||
return qm[rt];
|
||
}
|
||
|
||
int res=-inf;
|
||
if(L<=mid)res=max(res,qmax(lson,L,R));
|
||
if(R>mid)res=max(res,qmax(rson,L,R));
|
||
return res;
|
||
}
|
||
inline int qsum(int rt,int l,int r,int L,int R)
|
||
{
|
||
if(L<=l&&r<=R)
|
||
{
|
||
// printf("[%d]",rt);
|
||
return qs[rt];
|
||
}
|
||
|
||
int res=0;
|
||
if(L<=mid)res+=qsum(lson,L,R);
|
||
if(R>mid)res+=qsum(rson,L,R);
|
||
return res;
|
||
}
|
||
//以上是线段树
|
||
inline int q(int u,int v,bool tag)
|
||
{
|
||
|
||
int res=0;
|
||
if(tag) res=-inf;
|
||
while(top[u]!=top[v])
|
||
{
|
||
if(dep[top[u]]<dep[top[v]])
|
||
{
|
||
swap(u,v);
|
||
}
|
||
if(tag)res=max(res,qmax(1,1,n,nid[top[u]],nid[u]));
|
||
else res+=qsum(1,1,n,nid[top[u]],nid[u]);
|
||
// printf("(%d,%d,%d)",u,v,res);
|
||
u=fa[top[u]];
|
||
}
|
||
if(dep[u]>dep[v]) swap(u,v);
|
||
// printf("(%d,%d,%d)",nid[u],nid[v],res);
|
||
if(tag)res=max(res,qmax(1,1,n,nid[u],nid[v]));//son[u]->u边权放在儿子,所以连接儿子和爸爸的路要排除爸爸
|
||
else res+=qsum(1,1,n,nid[u],nid[v]);//接上,给的是点权就不用
|
||
return res;
|
||
}
|
||
inline void dfs1(int u,int f,int deep)
|
||
{
|
||
fa[u]=f;
|
||
dep[u]=deep;
|
||
siz[u]=1;
|
||
for(int i=h[u]; i; i=ne[i])
|
||
{
|
||
int v=to[i];//bug int
|
||
if(v==f) continue;//bug 放后了
|
||
// printf("(wo[%d]=val[%d]=%d)\n",v,i,val[i]);
|
||
dfs1(v,u,deep+1);
|
||
siz[u]+=siz[v];
|
||
if(son[u]==0||siz[v]>siz[son[u]])
|
||
{
|
||
son[u]=v;
|
||
}
|
||
}
|
||
// printf("out:%d:fa:%d,dep:%d,siz:%d\n",u,f,deep,siz[u]);
|
||
}
|
||
inline void dfs2(int u,int tp)
|
||
{
|
||
nid[u]=++cnt;
|
||
oid[cnt]=u;
|
||
top[u]=tp;
|
||
// printf("%d:nid:%d,nw:%d,top:%d\n",u,cnt,wo[u],topf);
|
||
if(!son[u]) return;
|
||
dfs2(son[u],tp);
|
||
for(int i=h[u]; i; i=ne[i])
|
||
{
|
||
v=to[i];
|
||
if(v!=fa[u]&&v!=son[u])
|
||
{
|
||
dfs2(v,v);
|
||
}
|
||
}
|
||
}
|
||
inline void pushup(int rt)
|
||
{
|
||
qm[rt]=max(qm[ls],qm[rs]);
|
||
qs[rt]=qs[ls]+qs[rs];
|
||
}
|
||
inline void change(int u,int w1,int rt,int l,int r)
|
||
{
|
||
if(l==r)
|
||
{
|
||
qm[rt]=w1;
|
||
qs[rt]=w1;
|
||
// printf("u:%d,a[%d]=%d(l=r=%d)\n",u,rt,w1,l);
|
||
}
|
||
else
|
||
{
|
||
if(u<=mid)
|
||
{
|
||
change(u,w1,lson);
|
||
}
|
||
else change(u,w1,rson);
|
||
pushup(rt);
|
||
// printf("u:%d,a[%d]=a[%d]%d/a[%d]%d\n",u,rt,ls,a[ls],rs,a[rs]);
|
||
}
|
||
}
|
||
int main()
|
||
{
|
||
//freopen("10.in","r",stdin);
|
||
//freopen("out.txt","w",stdout);
|
||
scanf("%d",&n);
|
||
cnt=0;
|
||
// cout<<"\\";
|
||
for(int i=1; i<n; i++)
|
||
{
|
||
scanf("%d%d",&u,&v);// 多打一个%d c0000005 APPCRASH
|
||
// printf("(%d)",i);
|
||
add(u,v);
|
||
add(v,u);
|
||
}
|
||
for(int i=1; i<=n; i++)
|
||
{
|
||
scanf("%d",&w[i]);
|
||
}
|
||
dfs1(1,0,1);
|
||
cnt=0;
|
||
dfs2(1,1);
|
||
build(1,1,cnt);
|
||
scanf("%d",&qu);
|
||
while(qu--)
|
||
{
|
||
scanf("%s",opt);
|
||
scanf("%d%d",&u,&v);
|
||
if(opt[1]=='M')
|
||
{
|
||
printf("%d\n",q(u,v,1));
|
||
}
|
||
else if(opt[1]=='S')
|
||
{
|
||
printf("%d\n",q(u,v,0));
|
||
}
|
||
else
|
||
{
|
||
change(nid[u],v,1,1,cnt);
|
||
}
|
||
}
|
||
return 0;
|
||
}
|