社区讨论
求助90分,最后一个点蜜汁WA
P3384【模板】重链剖分 / 树链剖分参与者 4已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mi7waupx
- 此快照首次捕获于
- 2025/11/21 04:40 4 个月前
- 此快照最后确认于
- 2025/11/21 04:40 4 个月前
CPP
#define range 1,cnt,1
#define ri register int
#define lson l,mid,u<<1
#define rson mid+1,r,u<<1|1
#define is_digit(c) ('0'<=(c) && (c)<='9')
#define morbi int l,int r,int u
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
struct edge{
int v,next;
}e[maxn<<1];
int ans_sum;
int n,m,root,p,cnt,ecnt;
int sum[maxn<<2],lazy[maxn<<2];
int dep[maxn],top[maxn],fa[maxn];
int seg[maxn],rev[maxn],son[maxn];
int head[maxn],num[maxn],size[maxn];
inline int read(){
int x=0;
char c=0;
bool flag=false;
while(!is_digit(c)) {flag|=c=='-';c=getchar();}
while(is_digit(c)) {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return flag?-x:x;
}
void initialization(){
seg[root]=1;
cnt=1; ecnt=0;
top[root]=rev[1]=root;
memset(sum,0,sizeof(sum));
memset(lazy,0,sizeof(lazy));
memset(size,0,sizeof(size));
memset(head,-1,sizeof(head));
}
void adde(int u,int v){
e[ecnt]=(edge){v,head[u]}; head[u]=ecnt++;
e[ecnt]=(edge){u,head[v]}; head[v]=ecnt++;
}
void dfs1(int u,int pre){
fa[u]=pre;
size[u]=1;
dep[u]=dep[pre]+1;
for(ri i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(v==pre) continue;
dfs1(v,u);
size[u]=(size[u]+size[v])%p;
if(size[v]>size[son[u]]) son[u]=v;
}
}
void dfs2(int u,int pre){
if(son[u]){
seg[son[u]]=++cnt;
top[son[u]]=top[u];
rev[cnt]=son[u];
dfs2(son[u],u);
}
for(ri i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(top[v] || v==pre) continue;
seg[v]=++cnt; rev[cnt]=top[v]=v;
dfs2(v,u);
}
}
inline void pushup(int u){
sum[u]=(sum[u<<1]+sum[u<<1|1])%p;
}
void pushdown(morbi){
int mid=l+r>>1;
lazy[u<<1]=(lazy[u<<1]+lazy[u])%p;
lazy[u<<1|1]=(lazy[u<<1|1]+lazy[u])%p;
sum[u<<1]=(lazy[u]*(mid-l+1)+sum[u<<1])%p;
sum[u<<1|1]=(lazy[u]*(r-mid)+sum[u<<1|1])%p;
lazy[u]=0;
}
void build(morbi){
if(l==r){
sum[u]=num[rev[l]];
return;
}
int mid=l+r>>1;
build(lson); build(rson);
pushup(u);
}
void update(int L,int R,int x,morbi){
if(L<=l && r<=R){
sum[u]=(sum[u]+x*(r-l+1))%p;
lazy[u]=(lazy[u]+x)%p;
return;
}
int mid=l+r>>1;
if(lazy[u]) pushdown(l,r,u);
if(L<=mid) update(L,R,x,lson);
if(R>mid) update(L,R,x,rson);
pushup(u);
}
int query(int L,int R,morbi){
if(L<=l && r<=R) return sum[u]%p;
int mid=l+r>>1,ret=0;
if(lazy[u]) pushdown(l,r,u);
if(L<=mid) ret=(ret+query(L,R,lson))%p;
if(R>mid) ret=(ret+query(L,R,rson))%p;
return ret;
}
void change(int L,int R,int x){
while(top[L]!=top[R]){
if(dep[top[L]]<dep[top[R]]) swap(L,R);
update(seg[top[L]],seg[L],x,range);
L=fa[top[L]];
}
if(dep[L]>dep[R]) swap(L,R);
update(seg[L],seg[R],x,range);
}
void getsum(int L,int R){
ans_sum=0;
while(top[L]!=top[R]){
if(dep[top[L]]<dep[top[R]]) swap(L,R);
ans_sum=(ans_sum+query(seg[top[L]],seg[L],range))%p;
L=fa[top[L]];
}
if(dep[L]>dep[R]) swap(L,R);
ans_sum=(ans_sum+query(seg[L],seg[R],range))%p;
}
int main(){
n=read(),m=read();
root=read(),p=read();
initialization();
for(ri i=1;i<=n;i++) num[i]=read()%p;
for(ri i=1;i<n;i++) adde(read(),read());
dfs1(root,0);
top[root]=rev[1]=root; seg[root]=1;
dfs2(root,0); build(range);
while(m--){
int op=read(),x,y,z;
if(op==1){
x=read(),y=read(),z=read();
change(x,y,z%p);
}
if(op==2){
x=read(),y=read()%p;
getsum(x,y);
printf("%d\n",ans_sum);
}
if(op==3){
x=read(),y=read();
update(seg[x],seg[x]+size[x]-1,y%p,range);
}
if(op==4){
x=read();
printf("%d\n",query(seg[x],seg[x]+size[x]-1,range)%p);
}
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...