社区讨论
帮帮弱小而无助的南瓜吧QAQ
P3384【模板】重链剖分 / 树链剖分参与者 4已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @mi6w9yvl
- 此快照首次捕获于
- 2025/11/20 11:51 4 个月前
- 此快照最后确认于
- 2025/11/20 11:51 4 个月前
1,3,4,8ac,9wa,其他全t了是为什么呀qwq
悄悄咪咪问一句,用不用开ll啊orz
CPP#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#define maxn 200010
#define maxm 400010
using namespace std;
int n,m,root,plane,u,v,x,y,z,cnt,tot,top,num,opt;
int fir[maxn],val[maxn],dfn[maxn],dep[maxn];
int fa[maxn],sz[maxn],wson[maxn],node[maxn],head[maxn];
int ll[maxn<<1],rr[maxn<<1],w[maxn<<1],tag[maxn<<1];
struct qwq
{
int to,nxt;
}e[maxm];
int read()
{
int xx=0,kk=1;char ch=' ';
while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
return kk*xx;
}
void addedge(int u,int v)
{
e[++num].to=v;
e[num].nxt=fir[u];
fir[u]=num;
}
void build(int l,int r,int num)
{
ll[num]=l,rr[num]=r;
if(l==r){w[num]=val[node[l]];return;}
int mid=(l+r)>>1;
build(l,mid,num<<1);
build(mid+1,r,num<<1|1);
w[num]=(w[num<<1]+w[num<<1|1])%plane;
}
void pushdown(int num)
{
w[num<<1]=(w[num<<1]+(rr[num<<1]-ll[num<<1]+1)*tag[num])%plane;
w[num<<1|1]=(w[num<<1|1]+(rr[num<<1|1]-ll[num<<1|1]+1)*tag[num])%plane;
tag[num<<1]=(tag[num<<1]+tag[num])%plane;
tag[num<<1|1]=(tag[num<<1|1]+tag[num])%plane;
tag[num]=0;
}
void add(int l,int r,int num,int k)
{
if(l>rr[num]||r<ll[num]) return;
if(l<=ll[num]&&r>=rr[num])
{
tag[num]=(tag[num]+k)%plane;
w[num]=(w[num]+(rr[num]-ll[num]+1)*k)%plane;
return;
}
pushdown(num);
add(l,r,num<<1,k);
add(l,r,num<<1|1,k);
w[num]=(w[num<<1]+w[num<<1|1])%plane;
}
int query(int l,int r,int num)
{
if(l>rr[num]||r<ll[num]) return 0;
if(l<=ll[num]&&r>=rr[num]) return w[num];
pushdown(num);
return (query(l,r,num<<1)+query(l,r,num<<1|1))%plane;
}
void dfs1(int u,int f)
{
fa[u]=f;sz[u]=1;
dep[u]=dep[f]+1;
for(int i=fir[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa[u]) continue;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[wson[u]]) wson[u]=v;
}
}
void dfs2(int u,int top)
{
dfn[u]=++tot,node[tot]=u,head[u]=top;
if(wson[u]) dfs2(wson[u],top);
for(int i=fir[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=fa[u]&&v!=wson[u]) dfs2(v,v);
}
}
void update(int x,int y,int z)
{
while(head[x]!=head[y])
{
if(dfn[head[x]]<dfn[head[y]]) swap(x,y);
add(dfn[head[x]],dfn[x],1,z),x=fa[head[x]];
}
if(dep[x]>dep[y]) swap(x,y);
add(dfn[x],dfn[y],1,z);
}
int getsum(int x,int y)
{
int ans=0;
while(head[x]!=head[y])
{
if(dfn[head[x]]<dfn[head[y]]) swap(x,y);
ans=(ans+query(dfn[head[x]],dfn[x],1))%plane;
x=fa[head[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=(ans+query(dfn[x],dfn[y],1))%plane;
return ans;
}
int main()
{
n=read(),m=read(),root=read(),plane=read();
for(int i=1;i<=n;++i)
val[i]=read()%plane;
for(int i=1;i<n;++i)
{
u=read(),v=read();
addedge(u,v),addedge(v,u);
}
dfs1(root,0),dfs2(root,1),build(1,n,1);
for(int i=1;i<=m;++i)
{
switch(opt=read())
{
case 1:{x=read(),y=read(),z=read()%plane;update(x,y,z);break;}
case 2:{x=read(),y=read();printf("%d\n",getsum(x,y));break;}
case 3:{x=read(),z=read()%plane;add(dfn[x],dfn[x]+sz[x]-1,1,z);break;}
case 4:{x=read();printf("%d\n",query(dfn[x],dfn[x]+sz[x]-1,1));break;}
}
}
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...