社区讨论
求调
P2590[ZJOI2008] 树的统计参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mhjsqb0v
- 此快照首次捕获于
- 2025/11/04 07:53 4 个月前
- 此快照最后确认于
- 2025/11/04 07:53 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll max(ll a,ll b){
return a>b?a:b;
}
inline ll min(ll a,ll b){
return a>b?b:a;
}
const int N=3e4+10;
int n,q;
int u,v;
struct segment_tree{
ll s[N<<2],mx[N<<2];
ll data[N];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void push_up(int p){
s[p]=s[ls(p)]+s[rs(p)];
mx[p]=max(mx[ls(p)],mx[rs(p)]);
}
void build(int p,int pl,int pr){
if(pl==pr){
s[p]=data[pl];
mx[p]=data[pl];
return ;
}
int mid=pl+(pr-pl>>1);
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
push_up(p);
}
void update(int p,int pl,int pr,int L,int R,ll k){
if(L<=pl&&pr<=R){
s[p]+=k;
mx[p]+=k;
return ;
}
int mid=pl+(pr-pl>>1);
if(L<=mid)update(ls(p),pl,mid,L,R,k);
if(mid+1<=R)update(rs(p),mid+1,pr,L,R,k);
push_up(p);
}
pair<ll,ll> query(int p,int pl,int pr,int L,int R){
if(L<=pl&&pr<=R){
return {mx[p],s[p]};
}
int mid=pl+(pr-pl>>1);
pair<ll,ll>ret={-1e18,0};
pair<ll,ll>tmp;
if(L<=mid){
tmp=query(ls(p),pl,mid,L,R);
ret.second+=tmp.second;
ret.first=max(ret.first,tmp.first);
}
if(mid+1<=R){
tmp=query(rs(p),mid+1,pr,L,R);
ret.second+=tmp.second;
ret.first=max(ret.first,tmp.first);
}
return ret;
}
};
struct cut_tree{
vector<int>G[N];
int fa[N],dep[N],siz[N],son[N],top[N],dfn[N],rank[N];
int cnt;
void init(int root){
cnt=0;
dep[root]=1;
}
void dfs1(int u){
son[u]=-1;
siz[u]=1;
for(auto v:G[u]){
if(dep[v])continue;
dep[v]=dep[u]+1;
fa[v]=u;
dfs1(v);
siz[u]+=siz[v];
if(son[u]==-1||siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int root){
top[u]=root;
dfn[u]=++cnt;
rank[cnt]=u;
if(son[u]==-1)return ;
dfs2(son[u],root);
for(auto v:G[u])
if(v!=son[u]&&v!=fa[u])
dfs2(v,v);
}
pair<ll,ll> query(int x,int y,segment_tree& tree){
pair<ll,ll>ret={-1e18,0};
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]>=dep[fy]){
ret.first=max(ret.first,tree.query(1,1,n,dfn[fx],dfn[x]).first);
ret.second+=tree.query(1,1,n,dfn[fx],dfn[x]).second;
x=fa[fx];
}
else{
ret.first=max(ret.first,tree.query(1,1,n,dfn[fy],dfn[y]).first);
ret.second+=tree.query(1,1,n,dfn[fx],dfn[x]).second;
y=fa[fy];
}
fx=top[x];
fy=top[y];
}
if(dfn[x]<dfn[y]){
ret.first=max(ret.first,tree.query(1,1,n,dfn[x],dfn[y]).first);
ret.second+=tree.query(1,1,n,dfn[x],dfn[y]).second;
}
else{
ret.first=max(ret.first,tree.query(1,1,n,dfn[x],dfn[y]).first);
ret.second+=tree.query(1,1,n,dfn[y],dfn[x]).second;
}
return ret;
}
};
segment_tree st;
cut_tree cut;
ll w[N];
string s;
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
cut.G[u].push_back(v);
cut.G[v].push_back(u);
}
for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
cut.init(1);
cut.dfs1(1);
cut.dfs2(1,1);
for(int i=1;i<=n;i++)st.data[i]=w[cut.rank[i]];
st.build(1,1,n);
scanf("%d",&q);
while(q--){
cin>>s;
scanf("%d%d",&u,&v);
if(s=="CHANGE"){
st.update(1,1,n,cut.dfn[u],cut.dfn[u],v);
}
else{
pair<ll,ll>ans=cut.query(u,v,st);
if(s=="QMAX"){
printf("%lld\n",ans.first);
}
else{
printf("%lld\n",ans.second);
}
}
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...