#include <bits/stdc++.h>
using namespace std;
#define maxn 30010
int AKIOI_maxd,AKIOI_sum,n,m,tot=0,head[maxn],top[maxn],rev[maxn],seg[maxn],f[maxn],w[maxn],dep[maxn],size[maxn],son[maxn];
struct edge {
int v,nxt;
}e[maxn<<1];
char s[10];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void add_(int u,int v) {
e[++tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
void dfs_1_(int u,int fa) {
dep[u]=dep[fa]+1;
f[u]=fa;
size[u]=1;
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
dfs_1_(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
void dfs_2_(int u,int fa) {
if(son[u]) {
seg[son[u]]=++seg[0];
top[son[u]]=top[u];
rev[seg[0]]=son[u];
dfs_2_(son[u],u);
}
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(!top[v]) {
seg[v]=++seg[0];
top[v]=v;
rev[seg[0]]=v;
dfs_2_(v,u);
}
}
}
struct seg_tree {
struct node {
int maxd,sum;
}tr[maxn<<2];
#define lson l,mid,nod<<1
#define rson mid+1,r,nod<<1|1
inline void pushup_(int nod) {
tr[nod].maxd=max(tr[nod<<1].maxd,tr[nod<<1|1].maxd);
tr[nod].sum=tr[nod<<1].sum+tr[nod<<1|1].sum;
}
void build_(int l,int r,int nod) {
if(l==r) {
tr[nod].maxd=tr[nod].sum=w[rev[l]];
return;
}
int mid=(l+r)>>1;
build_(lson);build_(rson);
pushup_(nod);
}
void update_(int l,int r,int nod,int k,int v) {
if(l==r&&l==k) {
tr[nod].maxd=tr[nod].sum=v;
return;
}
int mid=(l+r)>>1;
if(k<=mid) update_(lson,k,v);
else update_(rson,k,v);
pushup_(nod);
}
void query_(int l,int r,int nod,int LL,int RR) {
if(LL<=l&&RR>=r) {
AKIOI_maxd=max(AKIOI_maxd,tr[nod].maxd);
AKIOI_sum+=tr[nod].sum;
return;
}
int mid=(l+r)>>1;
if(LL<=mid) query_(lson,LL,RR);
if(RR>mid) query_(rson,LL,RR);
}
}tree_;
inline void solve_(int x,int y) {
AKIOI_maxd=-2139062143,AKIOI_sum=0;
int fx=top[x],fy=top[y];
while(fx!=fy) {
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
tree_.query_(1,seg[0],1,seg[fx],seg[x]);
x=f[fx];fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
tree_.query_(1,seg[0],1,seg[x],seg[y]);
}
void readda_(){
n=read_();
int x,y;memset(head,-1,sizeof(head));
for(int i=1;i<n;++i) {
x=read_();y=read_();
add_(x,y);add_(y,x);
}
for(int i=1;i<=n;++i) w[i]=read_();
dfs_1_(1,0);
seg[0]=seg[1]=top[1]=rev[1]=1;
dfs_2_(1,0);
tree_.build_(1,seg[0],1);
m=read_();
while(m--) {
scanf("%s",s);
x=read_();y=read_();
if(s[0]=='C') {
tree_.update_(1,seg[0],1,seg[x],y);
}
else if(s[1]=='M') {
solve_(x,y);
printf("%d\n",AKIOI_maxd);
}
else if(s[1]=='S') {
solve_(x,y);
printf("%d\n",AKIOI_sum);
}
}
}
int main() {
readda_();
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
int root,m,n,w[maxn],head[maxn],dep[maxn],top[maxn],seg[maxn],rev[maxn],f[maxn],size[maxn],son[maxn],tot=0;
struct edge {
int v,nxt;
}e[maxn<<1];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void add_(int u,int v) {
e[++tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
void dfs_1_(int u,int fa) {
dep[u]=dep[fa]+1;
f[u]=fa;size[u]=1;
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
dfs_1_(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
void dfs_2_(int u,int fa) {
if(son[u]) {
seg[son[u]]=++seg[0];
top[son[u]]=top[u];
rev[seg[0]]=son[u];
dfs_2_(son[u],u);
}
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
if(!top[v]) {
seg[v]=++seg[0];
top[v]=v;
rev[seg[0]]=v;
dfs_2_(v,u);
}
}
}
struct seg_tree {
struct node {
long long sum,la;
}tr[maxn<<2];
#define lson l,mid,nod<<1
#define rson mid+1,r,nod<<1|1
inline void pushup_(int nod) {
tr[nod].sum=tr[nod<<1].sum+tr[nod<<1|1].sum;
}
void build_(int l,int r,int nod) {
if(l==r) {
tr[nod].sum=w[rev[l]];
return ;
}
int mid=(l+r)>>1;
build_(lson);build_(rson);
pushup_(nod);
}
inline void xiugai_(int l,int r,int nod,long long v) {
tr[nod].sum += ( r-l+1 ) * v; tr[nod].la += v;
}
void update_(int l,int r,int nod,int LL,int RR,long long v) {
if(LL<=l&&RR>=r) {
xiugai_(l,r,nod,v);
return ;
}
int mid=(l+r)>>1;
if(tr[nod].la!=0) {
xiugai_(lson,tr[nod].la);xiugai_(rson,tr[nod].la);tr[nod].la=0;
}
if(LL<=mid) update_(lson,LL,RR,v);
if(RR>mid) update_(rson,LL,RR,v);
pushup_(nod);
}
long long query_(int l,int r,int nod,int LL,int RR) {
if(LL<=l&&RR>=r) return tr[nod].sum;
int mid=(l+r)>>1;
if(tr[nod].la!=0) {
xiugai_(lson,tr[nod].la);xiugai_(rson,tr[nod].la);tr[nod].la=0;
}
long long ans=0;
if(LL<=mid) ans+=query_(lson,LL,RR);
if(RR>mid) ans+=query_(rson,LL,RR);
return ans;
}
}tree_;
inline int LCA_(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return x;
}
inline int find_(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
if(f[top[x]]==y) return top[x];
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return son[x];
}
inline void solve_2_(int x,int y,long long z) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
tree_.update_(1,seg[0],1,seg[top[x]],seg[x],z);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
tree_.update_(1,n,1,seg[x],seg[y],z);
}
inline void solve_3_(int x,long long z) {
if(x==root) return tree_.update_(1,n,1,1,n,z);
int lca=LCA_(x,root);
if(lca!=x) return tree_.update_(1,n,1,seg[x],seg[x]+size[x]-1,z);
else {
int ch=find_(x,root);
tree_.update_(1,n,1,1,n,z);
tree_.update_(1,n,1,seg[ch],seg[ch]+size[ch]-1,-z);
return ;
}
}
inline void solve_4_(int x,int y) {
long long AKIOI=0;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
AKIOI+=tree_.query_(1,n,1,seg[top[x]],seg[x]);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
AKIOI+=tree_.query_(1,n,1,seg[x],seg[y]);
printf("%lld\n",AKIOI);
}
inline void solve_5_(int x) {
long long AKIOI=0;
if(x==root) {
AKIOI=tree_.query_(1,n,1,1,n);
printf("%lld\n",AKIOI);
return ;
}
int lca=LCA_(x,root);
if(lca!=x) AKIOI=tree_.query_(1,n,1,seg[x],seg[x]+size[x]-1);
else {
int ch=find_(x,root);
AKIOI=tree_.query_(1,n,1,1,n);
AKIOI-=tree_.query_(1,n,1,seg[ch],seg[ch]+size[ch]-1);
}
printf("%lld\n",AKIOI);
return ;
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) w[i]=read_();
int x;memset(head,-1,sizeof(head));
for(int i=2;i<=n;++i) {
x=read_();add_(i,x);add_(x,i);
}
dfs_1_(1,0);
seg[0]=seg[1]=rev[1]=top[1]=1;
dfs_2_(1,0);
tree_.build_(1,seg[0],1);
m=read_();root=1;
int pd,y,z;
while(m--) {
pd=read_();
if(pd==1) {
x=read_();
root=x;
}
else if(pd==2) {
x=read_();y=read_();z=read_();
solve_2_(x,y,(long long)z);
}
else if(pd==3) {
x=read_();z=read_();
solve_3_(x,(long long) z);
}
else if(pd==4) {
x=read_();y=read_();
solve_4_(x,y);
}
else if(pd==5) {
x=read_();
solve_5_(x);
}
}
}
int main() {
readda_();
return 0;
}
- 注意
d
f
s
2
dfs_2
dfs2时不要把
t
o
p
[
u
]
top[u]
top[u]打成
u
u
u
#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
int n,m,root,w[maxn],mod,tot=0,head[maxn],f[maxn],seg[maxn],top[maxn],rev[maxn],size[maxn],son[maxn],dep[maxn];
long long ans=0;
struct edge {
int v,nxt;
}e[maxn<<1];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void add_(int u,int v) {
e[++tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
void dfs_1_(int u,int fa) {
dep[u]=dep[fa]+1;
f[u]=fa;size[u]=1;
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
dfs_1_(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
void dfs_2_(int u,int fa) {
if(son[u]) {
seg[son[u]]=++seg[0];
top[son[u]]=top[u];
rev[seg[0]]=son[u];
dfs_2_(son[u],u);
}
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
if(!top[v]) {
seg[v]=++seg[0];
top[v]=v;
rev[seg[0]]=v;
dfs_2_(v,u);
}
}
}
struct seg_tree {
long long sum[maxn<<2],la[maxn<<2];
#define lson l,mid,nod<<1
#define rson mid+1,r,nod<<1|1
inline void pushup_(int nod) {
sum[nod]=sum[nod<<1]+sum[nod<<1|1];
sum[nod]%=mod;
}
void build_(int l,int r,int nod) {
if(l==r) {
sum[nod]=w[rev[l]];
sum[nod]%=mod;
return;
}
int mid=(l+r)>>1;
build_(lson);build_(rson);
pushup_(nod);
}
inline void xiugai_(int l,int r,int nod,int v) {
sum[nod]+=(long long) (r-l+1) * v;sum[nod]%=mod;
la[nod]+=v;
}
void update_(int l,int r,int nod,int LL,int RR,int v) {
if(LL<=l&&RR>=r) {
xiugai_(l,r,nod,v);
return;
}
int mid=(l+r)>>1;
if(la[nod]!=0) {
xiugai_(lson,la[nod]);xiugai_(rson,la[nod]);la[nod]=0;
}
if(LL<=mid) update_(lson,LL,RR,v);
if(RR>mid) update_(rson,LL,RR,v);
pushup_(nod);
}
void query_(int l,int r,int nod,int LL,int RR) {
if(LL<=l&&RR>=r) {
ans+=sum[nod];ans%=mod;
return ;
}
int mid=(l+r)>>1;
if(la[nod]!=0) {
xiugai_(lson,la[nod]);xiugai_(rson,la[nod]);la[nod]=0;
}
if(LL<=mid) query_(lson,LL,RR);
if(RR>mid) query_(rson,LL,RR);
}
}tree_;
inline void solve_update_(int x,int y,int z) {
z%=mod;
int fx=top[x],fy=top[y];
while(fx!=fy) {
if(dep[fx]<dep[fy]) {
swap(fx,fy); swap(x,y);
}
tree_.update_(1,n,1,seg[fx],seg[x],z);
x=f[fx];fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
tree_.update_(1,n,1,seg[x],seg[y],z);
}
inline void solve_query_(int x,int y) {
int fx=top[x],fy=top[y];
while(fx!=fy) {
if(dep[fx]<dep[fy]) {
swap(fx,fy);swap(x,y);
}
tree_.query_(1,n,1,seg[fx],seg[x]);
x=f[fx];fx=top[x];ans%=mod;
}
if(dep[x]>dep[y]) swap(x,y);
tree_.query_(1,n,1,seg[x],seg[y]); ans%=mod;
}
void readda_(){
n=read_();m=read_();root=read_();mod=read_();
for(int i=1;i<=n;++i) w[i]=read_();
int x,y;memset(head,-1,sizeof(head));
for(int i=1;i<n;++i) {
x=read_();y=read_();
add_(x,y);add_(y,x);
}
dfs_1_(root,0);
seg[0]=1;top[root]=root;seg[root]=1;rev[1]=root;
dfs_2_(root,0);
tree_.build_(1,n,1);
int pd,z;
while(m--) {
pd=read_();x=read_();
if(pd==1) {
y=read_();z=read_();
solve_update_(x,y,z);
}
else if(pd==2) {
y=read_();ans=0;
solve_query_(x,y);
printf("%lld\n",ans%mod);
}
else if(pd==3) {
z=read_();
tree_.update_(1,n,1,seg[x],seg[x]+size[x]-1,z);
}
else if(pd==4) {
ans=0;
tree_.query_(1,n,1,seg[x],seg[x]+size[x]-1);
printf("%lld\n",ans%mod);
}
}
}
int main() {
readda_();
return 0;
}
- 注意线段树修改函数的
v
v
v要开成
l
o
n
g
long
long
l
o
n
g
long
long
#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
int f[maxn],size[maxn],son[maxn],seg[maxn],top[maxn],rev[maxn],dep[maxn],n,m,tot=0,head[maxn],w[maxn];
long long ans;
struct edge {
int v,nxt;
}e[maxn<<1];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void add_(int u,int v) {
e[++tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
void dfs_1_(int u,int fa) {
dep[u]=dep[fa]+1;
f[u]=fa;size[u]=1;
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
dfs_1_(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
void dfs_2_(int u,int fa) {
if(son[u]) {
seg[son[u]]=++seg[0];
top[son[u]]=top[u];
rev[seg[0]]=son[u];
dfs_2_(son[u],u);
}
for(int i=head[u];~i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
if(!top[v]) {
seg[v]=++seg[0];
top[v]=v;
rev[seg[0]]=v;
dfs_2_(v,u);
}
}
}
struct seg_tree {
struct node {
long long sum,la;
}tr[maxn<<2];
#define lson l,mid,nod<<1
#define rson mid+1,r,nod<<1|1
inline void pushup_(int nod) {
tr[nod].sum=tr[nod<<1].sum+tr[nod<<1|1].sum;
}
void build_(int l,int r,int nod) {
if(l==r) {
tr[nod].sum=w[rev[l]];
return;
}
int mid=(l+r)>>1;
build_(lson);build_(rson);
pushup_(nod);
}
inline void xiugai_(int l,int r,int nod,long long v) {
tr[nod].sum+=(r-l+1) * v;tr[nod].la+=v;
}
void update_(int l,int r,int nod,int LL,int RR,long long v) {
if(LL<=l&&RR>=r) {
xiugai_(l,r,nod,v);
return ;
}
int mid=(l+r)>>1;
if(tr[nod].la!=0) {
xiugai_(lson,tr[nod].la);xiugai_(rson,tr[nod].la);tr[nod].la=0;
}
if(LL<=mid) update_(lson,LL,RR,v);
if(RR>mid) update_(rson,LL,RR,v);
pushup_(nod);
}
void query_(int l,int r,int nod,int LL,int RR) {
if(LL<=l&&RR>=r) {
ans+=tr[nod].sum;
return;
}
int mid=(l+r)>>1;
if(tr[nod].la!=0) {
xiugai_(lson,tr[nod].la);xiugai_(rson,tr[nod].la);tr[nod].la=0;
}
if(LL<=mid) query_(lson,LL,RR);
if(RR>mid) query_(rson,LL,RR);
}
}tree_;
inline void solve_query_(int x,int y) {
int fx=top[x],fy=top[y];
while(fx!=fy) {
if(dep[fx]<dep[fy]) {
swap(fx,fy);swap(x,y);
}
tree_.query_(1,seg[0],1,seg[fx],seg[x]);
x=f[fx];fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
tree_.query_(1,seg[0],1,seg[x],seg[y]);
}
void readda_() {
n=read_();m=read_();
for(int i=1;i<=n;++i) w[i]=read_();
int x,y;memset(head,-1,sizeof(head));
for(int i=1;i<n;++i) {
x=read_();y=read_();
add_(x,y);add_(y,x);
}
dfs_1_(1,0);
seg[0]=seg[1]=rev[1]=top[1]=1;
dfs_2_(1,0);
tree_.build_(1,seg[0],1);
int pd;
while(m--) {
pd=read_();x=read_();
if(pd==1) {
y=read_();
tree_.update_(1,seg[0],1,seg[x],seg[x],(long long)y);
}
else if(pd==2) {
y=read_();
tree_.update_(1,seg[0],1,seg[x],seg[x]+size[x]-1,(long long)y);
}
else if(pd==3) {
ans=0;
solve_query_(1,x);
printf("%lld\n",ans);
}
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}