我有个同学昨天晚上不知道为什么一点才睡觉,还要大半夜把我叫起来。今天迷迷糊糊敲了个代码让我找bug,然而我也没睡好,求助万能的谷民。树剖求调。
题目:P2590 [ZJOI2008]树的统计
传送门:https://www.luogu.com.cn/problem/P2590
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int x=0,f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
return f?-x:x;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+48);
}
struct node{
int next,to;
}e[1023213];
int head[10231312],cnt,tot,n,m,x,y,z,a[10231312];
int pre[10231231],dfn[10231312],top[10231312],dep[1023123],fa[10213123],size[1023123],son[1023123];
void add(int u,int v) {
e[++cnt].next=head[u];
e[cnt].to=v;
head[u]=cnt;
}
namespace ss{
#define lson pos<<1
#define rson pos<<1|1
struct node{
int sum,maxx,lazy;
}tree[1023123];
void build(int pos,int l,int r) {
if (l==r) {
tree[pos].sum=a[pre[l]];
tree[pos].maxx=tree[pos].sum;
return ;
}
int mid=l+r>>1;
build(lson,l,mid); build(rson,mid+1,r);
tree[pos].sum=tree[lson].sum+tree[rson].sum;
tree[pos].maxx=max(tree[lson].maxx,tree[rson].maxx);
}
void change(int pos,int l,int r,int L,int R,int k) {
if (l>=L && r<=R) {
tree[pos].sum=k; tree[pos].maxx=k;
return ;
}
int mid=l+r>>1;
if (L<=mid) change(lson,l,mid,L,R,k);
if (R>mid) change(rson,mid+1,r,L,R,k);
tree[pos].sum=tree[lson].sum+tree[rson].sum;
tree[pos].maxx=(tree[lson].maxx,tree[rson].maxx);
}
int query(int pos,int l,int r,int L,int R) {
if (l>=L && r<=R) return tree[pos].sum;
int mid=l+r>>1,res=0;
if (L<=mid) res+=query(lson,l,mid,L,R);
if (R>mid) res+=query(rson,mid+1,r,L,R);
return res;
}
int m_query(int pos,int l,int r,int L,int R) {
if (l>=L && r<=R) return tree[pos].maxx;
int mid=l+r>>1,res=-0x7ffffff;
if (L<=mid) res=max(res,m_query(lson,l,mid,L,R));
if (R>mid) res=max(res,m_query(rson,mid+1,r,L,R));
return res;
}
}
namespace sp{
void dfs1(int now,int Fa){
size[now]=1; dep[now]=dep[Fa]+1; fa[now]=Fa;
for (int i=head[now];i;i=e[i].next) {
if (e[i].to==Fa) continue;
dfs1(e[i].to,now);
size[now]+=size[e[i].to];
if (size[son[now]]<size[e[i].to]) son[now]=e[i].to;
}
}
void dfs2(int now,int Top) {
dfn[now]=++tot; pre[tot]=now; top[now]=Top;
if (son[now]) dfs2(son[now],Top);
for (int i=head[now];i;i=e[i].next) {
if (e[i].to==fa[now]||e[i].to==son[now]) continue;
dfs2(e[i].to,e[i].to);
}
}
int query(int x,int y) {
int res=0;
while(top[x]!=top[y]) {
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res+=ss::query(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
res+=ss::query(1,1,n,dfn[x],dfn[y]);
return res;
}
int m_query(int x,int y) {
int res=-0x7ffffff;
while(top[x]!=top[y]) {
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res=max(res,ss::m_query(1,1,n,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
res=max(res,ss::m_query(1,1,n,dfn[x],dfn[y]));
return res;
}
}
signed main() {
n=read();
for (int i=1;i<n;++i) {
x=read(); y=read();
add(x,y); add(y,x);
}
for (int i=1;i<=n;++i) a[i]=read();
sp::dfs1(1,0); sp::dfs2(1,1);
ss::build(1,1,n);
m=read();
for (int i=1;i<=m;++i) {
string s;
cin>>s;
if (s[1]=='M') {
x=read(); y=read();
print(sp::m_query(x,y)); putchar('\n');
}
else if (s[1]=='S') {
x=read(); y=read();
print(sp::query(x,y)); putchar('\n');
}
else if (s[1]=='H') {
x=read(); z=read();
ss::change(1,1,n,dfn[x],dfn[x],z);
}
}
return 0;
}