社区讨论
看在你老婆亚丝娜的份上帮小舅子一把
P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mi6vafel
- 此快照首次捕获于
- 2025/11/20 11:24 4 个月前
- 此快照最后确认于
- 2025/11/20 11:24 4 个月前
蜜汁wa了2,9,10,%过了,longlong也开了,数组也够大,请问是什么问题?
拜托了
CPP#include<bits/stdc++.h>
using namespace std;
const int N=100010;
struct Way{
int to,next;
} way[N<<1];
int n,m,r,flag,cnt,t,head[N];
int num,fa[N],dep[N],size[N],son[N],top[N],dfn[N],rev[N];
long long p,a,b,c,first[N],lazy[N],tree[N<<2],val[N];
void addway(int u,int v){
way[++cnt].to=v;
way[cnt].next=head[u];
head[u]=cnt;
}
void dfs1(int cur,int f,int d){
fa[cur]=f; dep[cur]=d; size[cur]=1;
int maxx=-1;
for(int i=head[cur];i;i=way[i].next){
if(way[i].to==f) continue;
dfs1(way[i].to,cur,d+1);
size[cur]+=size[way[i].to];
if(size[way[i].to]>maxx) {
maxx=size[way[i].to]; son[cur]=way[i].to;
}
}
}
void dfs2(int cur,int topf){
top[cur]=topf; dfn[cur]=++t; rev[t]=cur; first[t]=val[cur];
if(!son[cur]) return;
dfs2(son[cur],topf);
for(int i=head[cur];i;i=way[i].next){
if(way[i].to==fa[cur]||way[i].to==son[cur]) continue;
dfs2(way[i].to,way[i].to);
}
}
void pushdown(int o,int l,int r,int mid){
tree[o<<1]=(tree[o<<1]+lazy[o]*(mid-l+1)%p)%p;
lazy[o<<1]=(lazy[o<<1]+lazy[o]%p)%p;
tree[o<<1|1]=(tree[o<<1|1]+lazy[o]*(r-mid)%p)%p;
lazy[o<<1|1]=(lazy[o<<1|1]+lazy[o]%p)%p;
lazy[o]=0;
}
void maketree(int o,int l,int r){
if(l==r){
tree[o]=first[l]%p; return;
}
int mid=l+r>>1;
maketree(o<<1,l,mid);
maketree(o<<1|1,mid+1,r);
tree[o]=(tree[o<<1]+tree[o<<1|1])%p;
}
void insert(int o,int l,int r,int x,int y,long long v){
if(x<=l&&r<=y){
tree[o]=(tree[o]+v*(r-l+1))%p; lazy[o]=(lazy[o]+v)%p; return;
}
int mid=l+r>>1;
if(lazy[o]) pushdown(o,l,r,mid);
if(x<=mid) insert(o<<1,l,mid,x,y,v);
if(y>mid) insert(o<<1|1,mid+1,r,x,y,v);
tree[o]=(tree[o<<1]+tree[o<<1|1])%p;
}
long long sum(int o,int l,int r,int x,int y){
if(x<=l&&r<=y) return tree[o]%p;
int mid=l+r>>1,tot=0;
if(lazy[o]) pushdown(o,l,r,mid);
if(x<=mid) tot+=sum(o<<1,l,mid,x,y);
if(y>mid) tot+=sum(o<<1|1,mid+1,r,x,y);
return tot%p;
}
void add(int x,int y,long long v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
insert(1,1,n,dfn[top[x]],dfn[x],v);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
insert(1,1,n,dfn[y],dfn[x],v);
}
long long dis(int x,int y){
long long ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=(ans+sum(1,1,t,dfn[top[x]],dfn[x]))%p;
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
ans=(ans+sum(1,1,t,dfn[y],dfn[x]))%p;
return ans%p;
}
int main(){
freopen("data.in","r",stdin);
scanf("%d %d %d %lld",&n,&m,&r,&p);
for(int i=1;i<=n;i++)
scanf("%lld",&val[i]);
for(int i=1;i<=n-1;i++){
scanf("%d %d",&a,&b);
addway(a,b); addway(b,a);
}
dfs1(r,0,1); dfs2(r,r);
maketree(1,1,t);
for(int i=1;i<=m;i++){
scanf("%d",&flag);
if(flag==1){
scanf("%lld %lld %lld",&a,&b,&c); c%=p;
add(a,b,c);
}
else if(flag==2){
scanf("%lld %lld",&a,&b);
printf("%lld\n",dis(a,b)%p);
}
else if(flag==3){
scanf("%lld %lld",&a,&b); b%=p;
insert(1,1,t,dfn[a],dfn[a]+size[a]-1,b);
}
else {
scanf("%lld",&a);
printf("%lld\n",sum(1,1,t,dfn[a],dfn[a]+size[a]-1)%p);
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...