#include<iostream>
#include<vector>
#define MAXN 100000
using namespace std;
int f[MAXN*4+10],S[MAXN*4+10],M[MAXN*4+10],a[MAXN+10],n;
int de[MAXN+10],son[MAXN+10],fa[MAXN+10],siz[MAXN+10];
int ind[MAXN+10],cnt=0,top[MAXN+10],who[MAXN+10];
vector<int>tree[MAXN+10];
int ls(int now){return now<<1; }
int rs(int now){return now<<1|1;}
void push_up(int now)
{
S[now]=S[ls(now)]+S[rs(now)];
M[now]=max(M[ls(now)],M[rs(now)]);
}
void build(int l,int r,int now)
{
if(l==r)
{
S[now]=M[now]=a[who[l]];
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls(now));
build(mid+1,r,rs(now));
push_up(now);
}
int ask_max(int l,int r,int s,int t,int now)
{
if(l<=s&&t<=r)return M[now];
cout<<l<<' '<<r<<' '<<s<<' '<<t<<' '<<now<<endl;
int mid=(s+t)>>1,maxn=-725;
if(l<=mid)maxn=max(maxn,ask_max(l,r,s,mid ,ls(now)));
if(r>mid)maxn=max(maxn,ask_max(l,r,mid+1,t,rs(now)));
return maxn;
}
int ask_sum(int l,int r,int s,int t,int now)
{
if(l<=s&&t<=r)return S[now];
int mid=(s+t)>>1,sum=0;
if(l<=mid)sum+=(ask_sum(l,r,s,mid ,ls(now)));
if(r>mid)sum+=(ask_sum(l,r,mid+1,t,rs(now)));
return sum;
}
void updata(int q,int s,int t,int now,int val)
{
int mid=(s+t)>>1;
if(s==t)
{
S[now]=M[now]=val;
return ;
}
if(q<=mid)updata(q,s,mid,ls(now),val);
else updata(q,mid+1,t,rs(now),val);
push_up(now);
}
//线段树
void dfs1(int u,int fat)
{
siz[u]=1,fa[u]=fat,de[u]=de[fat]+1;
int maxn=0;
for(int p=0;p<tree[u].size();p++)
{
int v=tree[u][p];
if(v==fat)continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>maxn)
son[u]=v,maxn=siz[v];
}
}
void dfs2(int u,int T)
{
ind[u]=++cnt,who[cnt]=u,top[u]=T;
if(!son[u])return ;
dfs2(son[u],T);
for(int p=0;p<tree[u].size();p++)
{
int v=tree[u][p];
if(v!=fa[u])
if(v!=son[u])
dfs2(v,v);
}
}
//树剖预处理
int QMAX(int u,int v)
{
int maxn=-0x3f3f3f3f;
while(top[u]!=top[v])
{
if(de[top[u]]>de[top[v]])swap(u,v);
maxn=max(maxn,ask_max(ind[top[u]],ind[u],1,n,1));
u=fa[top[u]];
}
if(de[u]>de[v])swap(u,v);
maxn=max(maxn,ask_max(ind[u],ind[v],1,n,1));
return maxn;
}
int QSUM(int u,int v)
{
int sum=0;
while(top[u]!=top[v])
{
if(de[top[u]]>de[top[v]])swap(u,v);
sum+=ask_sum(ind[top[u]],ind[u],1,n,1);
u=fa[top[u]];
}
if(de[u]>de[v])swap(u,v);
sum+=ask_sum(ind[u],ind[v],1,n,1);
return sum;
}
void CHANGE(int u,int val)
{
updata(who[u],1,n,1,val);
}
//树剖
void link(int x,int y)
{
tree[x].push_back(y);
tree[y].push_back(x);
}
void test()
{
for(int p=1;p<=n;p++)
cout<<p<<" siz"<<siz[p]<<" fa"<<fa[p]<<" de"<<de[p]<<endl;
for(int p=1;p<=n;p++)
cout<<p<<" ind"<<ind[p]<<" "<<top[p]<<endl;
}
signed main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
for(int p=1,x,y;p<n;p++)
cin>>x>>y,link(x,y);
for(int p=1;p<=n;p++)
cin>>a[p];
de[1]=1,fa[1]=1;
dfs1(1,-1),dfs2(1,1);
build(1,n,1);
test();
int q;
cin>>q;
string str;
while(q--)
{
int x,y;
cin>>str>>x>>y;
if(str[1]=='H')CHANGE(x,y);
else if(str[1]='M')cout<<QMAX(x,y)<<endl;
else if(str[1]='S')cout<<QSUM(x,y)<<endl;
}
}
目测是 ask_max 函数出错了,里面有调试的输出。l 和 r 是要找的目标区间,传参传着传着他就变成 0 0 了,然后就死循环了。
萌新很懵,求助大佬啊/kk