重链剖分:
#include<bits/stdc++.h>
#define N 400005
#define M 400005
//#define int long long
#define ls (w<<1)
#define rs ((w<<1)|1)
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^48),
ch=getchar();
return x*f;
}
inline void write(int x){
int tmp=x<0?-x:x,cnt=0;char f[70];
if(!x)
putchar('0');
if(x<0)
putchar('-');
while(tmp){
f[cnt++]=tmp%10+'0';
tmp/=10;
}
while(cnt)
putchar(f[--cnt]);
putchar('\n');
}
int head[N],nxt[M],to[M],t,u,v;
inline void add(){
nxt[++t]=head[u],head[u]=t,to[t]=v,
nxt[++t]=head[v],head[v]=t,to[t]=u;
}
int n,m,V[N],b[N<<2],d[N],id,dfn[N];
int son[N],top[N],f[N],sz[N],dep[N],maxn[N<<2];
inline void push_up(int w){
b[w]=b[ls]+b[rs],
maxn[w]=max(maxn[ls],maxn[rs]);
}
inline void build(int w,int l,int r){
if(l==r){
maxn[w]=b[w]=d[l];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid),
build(rs,mid+1,r),
push_up(w);
}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,
sz[x]=1,
f[x]=fa;
int maxson=0;
for(int i=head[x];i;i=nxt[i])
if(to[i]!=fa)
dfs1(to[i],x),
sz[i]+=sz[to[i]],
maxson=sz[to[i]]>sz[maxson]?to[i]:maxson;
son[x]=maxson;
}
inline void dfs2(int x,int tp){
dfn[x]=++id,
d[id]=V[x],
top[x]=tp;
if(son[x])
dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(to[i]!=f[x]&&to[i]!=son[x])
dfs2(to[i],to[i]);
}
inline void update(int w,int l,int r,int x,int k){
if(l==r){
maxn[w]=b[w]=k;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
update(ls,l,mid,x,k);
else
update(rs,mid+1,r,x,k);
push_up(w);
}
inline int querymax(int w,int l,int r,int L,int R){
if(L<=l&&R>=r)
return maxn[w];
int mid=(l+r)>>1,res=-1e9;
if(L<=mid)
res=querymax(ls,l,mid,L,R);
if(R>mid)
res=max(res,querymax(rs,mid+1,r,L,R));
return res;
}
inline int querysum(int w,int l,int r,int L,int R){
// if(L>R || L<1 || R>n) return 0;
if(L<=l&&R>=r)
return b[w];
int mid=((l+r)>>1),res=0;
if(L<=mid)
res=querysum(ls,l,mid,L,R);
if(R>mid)
res+=querysum(rs,mid+1,r,L,R);
return res;
}
inline int requerysum(int l,int r){
int res=0;
while(top[l]!=top[r]){
if(dep[top[l]]<dep[top[r]])
swap(l,r);
res+=querysum(1,1,n,dfn[top[l]],dfn[l]),
l=f[top[l]];
}
if(dep[l]>dep[r])
swap(l,r);
return res+querysum(1,1,n,dfn[l],dfn[r]);
}
inline int requerymax(int l,int r){
int res=-1e9;
while(top[l]!=top[r]){
if(dep[top[l]]<dep[top[r]])
swap(l,r);
res=max(res,querymax(1,1,n,dfn[top[l]],dfn[l])),
l=f[top[l]];
}
if(dep[l]>dep[r])
swap(l,r);
return max(res,querymax(1,1,n,dfn[l],dfn[r]));
}
char s[100];
signed main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
n=read();
for(int i=1;i<n;++i)
u=read(),v=read(),
add();
for(int i=1;i<=n;++i)
V[i]=read();
sz[0]=-1e9,
dfs1(1,0),
dfs2(1,1),
build(1,1,n),
m=read();
while(m--){
scanf("%s",s),
u=read(),v=read();
if(*s=='C')
update(1,1,n,dfn[u],v);
else if(*s=='Q'&&s[1]=='M')
write(requerymax(u,v));
else
write(requerysum(u,v));
}
return 0;
}
长链剖分:
#include<bits/stdc++.h>
#define N 400005
#define M 400005
//#define int long long
#define ls (w<<1)
#define rs ((w<<1)|1)
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^48),
ch=getchar();
return x*f;
}
inline void write(int x){
int tmp=x<0?-x:x,cnt=0;char f[70];
if(!x)
putchar('0');
if(x<0)
putchar('-');
while(tmp){
f[cnt++]=tmp%10+'0';
tmp/=10;
}
while(cnt)
putchar(f[--cnt]);
putchar('\n');
}
int head[N],nxt[M],to[M],t,u,v;
inline void add(){
nxt[++t]=head[u],head[u]=t,to[t]=v,
nxt[++t]=head[v],head[v]=t,to[t]=u;
}
int n,m,V[N],b[N<<2],d[N],id,dfn[N];
int son[N],top[N],f[N],dep[N],sz[N],maxn[N<<2];
inline void push_up(int w){
b[w]=b[ls]+b[rs],
maxn[w]=max(maxn[ls],maxn[rs]);
}
inline void build(int w,int l,int r){
if(l==r){
maxn[w]=b[w]=d[l];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid),
build(rs,mid+1,r),
push_up(w);
}
inline void dfs1(int x,int fa){
sz[x]=dep[x]=dep[fa]+1,
f[x]=fa;
int maxson=0;
for(int i=head[x];i;i=nxt[i])
if(to[i]!=fa){
dfs1(to[i],x);
if(sz[to[i]]>sz[x])
maxson=to[i],
sz[x]=sz[to[i]];
}
son[x]=maxson;
}
inline void dfs2(int x,int tp){
dfn[x]=++id,
d[id]=V[x],
top[x]=tp;
if(son[x])
dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(to[i]!=f[x]&&to[i]!=son[x])
dfs2(to[i],to[i]);
}
inline void update(int w,int l,int r,int x,int k){
if(l==r){
maxn[w]=b[w]=k;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
update(ls,l,mid,x,k);
else
update(rs,mid+1,r,x,k);
push_up(w);
}
inline int querymax(int w,int l,int r,int L,int R){
if(L<=l&&R>=r)
return maxn[w];
int mid=(l+r)>>1,res=-1e9;
if(L<=mid)
res=querymax(ls,l,mid,L,R);
if(R>mid)
res=max(res,querymax(rs,mid+1,r,L,R));
return res;
}
inline int querysum(int w,int l,int r,int L,int R){
// if(L>R || L<1 || R>n) return 0;
if(L<=l&&R>=r)
return b[w];
int mid=((l+r)>>1),res=0;
if(L<=mid)
res=querysum(ls,l,mid,L,R);
if(R>mid)
res+=querysum(rs,mid+1,r,L,R);
return res;
}
inline int requerysum(int l,int r){
int res=0;
while(top[l]!=top[r]){
if(dep[top[l]]<dep[top[r]])
swap(l,r);
res+=querysum(1,1,n,dfn[top[l]],dfn[l]),
l=f[top[l]];
}
if(dep[l]>dep[r])
swap(l,r);
return res+querysum(1,1,n,dfn[l],dfn[r]);
}
inline int requerymax(int l,int r){
int res=-1e9;
while(top[l]!=top[r]){
if(dep[top[l]]<dep[top[r]])
swap(l,r);
res=max(res,querymax(1,1,n,dfn[top[l]],dfn[l])),
l=f[top[l]];
}
if(dep[l]>dep[r])
swap(l,r);
return max(res,querymax(1,1,n,dfn[l],dfn[r]));
}
char s[100];
signed main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
n=read();
for(int i=1;i<n;++i)
u=read(),v=read(),
add();
for(int i=1;i<=n;++i)
V[i]=read();
sz[0]=-1e9,
dfs1(1,0),
dfs2(1,1),
build(1,1,n),
m=read();
while(m--){
scanf("%s",s),
u=read(),v=read();
if(*s=='C')
update(1,1,n,dfn[u],v);
else if(*s=='Q'&&s[1]=='M')
write(requerymax(u,v));
else
write(requerysum(u,v));
}
return 0;
}
不一样的地方:
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,
sz[x]=1,
f[x]=fa;
int maxson=0;
for(int i=head[x];i;i=nxt[i])
if(to[i]!=fa)
dfs1(to[i],x),
sz[i]+=sz[to[i]],
maxson=sz[to[i]]>sz[maxson]?to[i]:maxson;
son[x]=maxson;
}
inline void dfs1(int x,int fa){
sz[x]=dep[x]=dep[fa]+1,
f[x]=fa;
int maxson=0;
for(int i=head[x];i;i=nxt[i])
if(to[i]!=fa){
dfs1(to[i],x);
if(sz[to[i]]>sz[x])
maxson=to[i],
sz[x]=sz[to[i]];
}
son[x]=maxson;
}
调了很久了,是蒟蒻常数太大了吗QWQ