社区讨论
萌新求助,样例输出0
P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lo87047r
- 此快照首次捕获于
- 2023/10/27 13:48 2 年前
- 此快照最后确认于
- 2023/10/27 13:48 2 年前
照着题解第一篇写的,线段树部分不一样
CPP#include<bits/stdc++.h>
#define pushup(now) tree[now]=tree[now<<1]+tree[now<<1|1]
#define Max 200100
using namespace std;
int arr[Max],head[Max<<2],son[Max],id[Max],fa[Max],dep[Max],siz[Max],top[Max],vn[Max];
int cnt,num,mod,n,m,r,res;
struct node
{
int l,r,len,sum,tag;
node operator+(const node &x)const
{
return {l,x.r,len+x.len,sum+x.sum,0};
}
}tree[Max<<2];
struct Edge
{
int to,nxt,v;
}e[Max<<2];
inline void read(int &x)
{
x=0;
int 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^48);
c=getchar();
}
x*=f;
}
inline void add(int from,int to)
{
e[++cnt].nxt=head[from];
e[cnt].to=to;
//e[cnt].v=v;
head[from]=cnt;
}
void build(int now,int x,int y)
{
if(x==y)
{
tree[now]={x,x,1,vn[x],0};
return;
}
int mid=(x+y)>>1;
build(now<<1,x,mid);
build(now<<1|1,mid+1,y);
pushup(now);
}
inline void givetag(int now,int tag)
{
if(tree[now].len==1)
{
tree[now].sum+=tag;
return;
}
tree[now].sum+=tag*tree[now].len;
tree[now].tag+=tag;
}
inline void pushdown(int now)
{
givetag(now<<1,tree[now].tag);
givetag(now<<1|1,tree[now].tag);
tree[now].tag=0;
}
int query(int now,int x,int y)
{
if(tree[now].tag) pushdown(now);
if(x>tree[now].r||y<tree[now].l) return 0;
else if(x<=tree[now].l&&y>=tree[now].r)
{
res+=tree[now].sum;
res%=mod;
return 0;
}
else return query(now<<1,x,y)+query(now<<1|1,x,y);
}
void modify(int now,int x,int y,int v)
{
if(tree[now].tag)pushdown(now);
if(x>tree[now].r||y<tree[now].l) return;
else if(x<=tree[now].l&&y>=tree[now].r)
{
givetag(now,v);
return;
}
else modify(now<<1,x,y,v),modify(now<<1|1,x,y,v);
pushup(now);
}
inline void dfs1(int x,int f,int deep)
{
dep[x]=deep;
fa[x]=f;
siz[x]=1;
int maxsiz=-1;
for(int i=head[x];i;i=e[i].nxt)
{
int t=e[i].to;
if(t==f)
continue;
dfs1(t,x,deep+1);
siz[x]+=siz[t];
if(siz[t]>maxsiz)
{
son[x]=t;
maxsiz=siz[t];
}
}
}
inline void dfs2(int x,int topf)
{
id[x]=++cnt;
vn[cnt]=arr[x];
top[x]=topf;
if(!son[x])
return;
dfs2(son[x],topf);
for(int i=head[x];i;i=e[i].nxt)
{
int t=e[i].to;
if(t==fa[x]||t==son[x])
continue;
dfs2(t,t);
}
}
inline void qrange(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
res=0;
query(1,x,y);
ans+=res;
ans%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
res=0;
query(r,id[x],id[y]);
ans+=res;
printf("%d",ans%mod);
}
inline void uprange(int x,int y,int z)
{
z%=mod;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
modify(1,id[x],id[x]+siz[x]-1,z);
x=fa[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
modify(r,id[x],id[y],z);
}
inline void qson(int x)
{
res=0;
query(r,id[x],id[x]+siz[x]-1);
printf("%d",res%mod);
}
inline void upson(int x,int z)
{
modify(r,id[x],id[x]+siz[x]-1,z);
}
int main()
{
read(n),read(m),read(r),read(mod);
for(int i=1;i<=n;++i)
read(arr[i]);
for(int i=1;i<n;++i)
{
int t1,t2;
read(t1),read(t2);
add(t1,t2),add(t2,t1);
}
dfs1(r,0,1),dfs2(r,r),build(r,1,n);
for(int i=1;i<=m;++i)
{
int t,x,y,z;
read(t);
if(t==1)
{
read(x),read(y),read(z);
uprange(x,y,z);
}
if(t==2)
{
read(x),read(y);
qrange(x,y);
}
if(t==3)
{
read(x),read(z);
upson(x,z);
}
if(t==4)
{
read(x);
qson(x);
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...