社区讨论
萌新求调,悬赏一个关注
P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo881j29
- 此快照首次捕获于
- 2023/10/27 14:17 2 年前
- 此快照最后确认于
- 2023/10/27 14:17 2 年前
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct csy
{
int to;
int next;
}edge[500000];
struct nb
{
int data;
int l;
int r;
}node[5000000];
int n,m,r,p,w[500000],x,y,k,kk,z,dep[5000000],fa[5000000],wt[5000000],topp[500000],nod[5000000],add[5000000],noe[50000000];
void sadd(int x,int y)
{
++kk;
edge[kk].to=y;
edge[kk].next=noe[x];
noe[x]=kk;
}
void spread(int x)
{
if(add[x])
{
node[2*x].data=(node[2*x].data+add[x]*(node[2*x].r-node[2*x].l+1)%p)%p;
node[2*x+1].data=(node[2*x+1].data+add[x]*(node[2*x+1].r-node[2*x+1].l+1)%p)%p;
add[2*x]=(add[2*x]+add[x])%p;
add[2*x+1]=(add[2*x+1]+add[x])%p;
add[x]=0;
}
}
void addd(int x,int l,int r,int z)
{
if(l<=node[x].l&&node[x].r<=r)
{
node[x].data=(node[x].data+(node[x].r-node[x].l+1)*z%p)%p;
add[x]=(add[x]+z)%p;
return ;
}
spread(x);
int mid=(node[x].l+node[x].r)>>1;
if(l<=mid)
addd(2*x,l,r,z);
if(r>=mid+1)
addd(2*x+1,l,r,z);
node[x].data=(node[2*x].data+node[2*x+1].data)%p;
}
void build(int x,int l,int r)
{
node[x].l=l;
node[x].r=r;
if(l==r)
{
node[x].data=w[wt[l]];
return ;
}
int mid=(l+r)>>1;
build(2*x,l,mid);
build(2*x+1,mid+1,r);
node[x].data=(node[2*x].data%p+node[2*x+1].data%p)%p;
}
int quer(int x,int l,int r)
{
if(l<=node[x].l&&node[x].r<=r)
{
return node[x].data;
}
spread(x);
long long ans=0;
int mid=(node[x].l+node[x].r)>>1;
if(l<=mid)
ans=(ans+quer(2*x,l,r))%p;
if(r>mid)
ans=(ans+quer(2*x+1,l,r))%p;
return ans;
}
int siz[500000],mxson[500000];
void dfs(int u,int f)
{
dep[u]=dep[f]+1;
fa[u]=f;
siz[u]=1;
int temp=0;
mxson[u]=0;
for(int i=noe[u];i;i=edge[i].next)
{
int son=edge[i].to;
if(son==f)
continue;
dfs(son,u);
siz[u]+=siz[son];
if(siz[son]>temp)
{
temp=siz[son];
mxson[u]=son;
}
}
}
int cont=0;
void dfs2(int u,int top)
{
++cont;
nod[u]=cont;
wt[cont]=u;
topp[u]=top;
if(mxson[u]!=0)
dfs2(mxson[u],top);
else return;
for(int i=noe[u];i;i=edge[i].next)
{
int son=edge[i].to;
if(son==fa[u]||son==mxson[u])
{
continue;
}
dfs2(son,son);
}
}
int qsum(int x,int y)
{
long long ans=0;
while(topp[x]!=topp[y])
{
if(dep[x]<dep[y])
swap(x,y);
ans=(ans+quer(1,nod[topp[x]],nod[x]))%p;
x=fa[topp[x]];
}
if(dep[x]<dep[y])
swap(x,y);
ans=(ans+quer(1,nod[y],nod[x]))%p;
return ans;
}
void qadd(int x,int y,int z)
{
while(topp[x]!=topp[y])
{
if(dep[x]<dep[y])
swap(x,y);
addd(1,nod[topp[x]],nod[x],z);
x=fa[topp[x]];
}
if(dep[x]<dep[y])
swap(x,y);
addd(1,nod[y],nod[x],z);
}
void qson(int x,int z)
{
addd(1,nod[x],nod[x]+siz[x]-1,z);
}
int qqqsum(int x)
{
long long ans=0;
ans=(ans+quer(1,nod[x],nod[x]+siz[x]-1))%p;
return ans;
}
signed main()
{
int size(1500<<20); // 512M
__asm__ ( "movq %0, %%rsp\n"::"r"((char*)malloc(size)+size));
freopen("66.in","r",stdin);
freopen("66.out","w",stdout);
cin>>n>>m>>r>>p;
for(int i=1;i<=n;i++)
{
cin>>w[i];
}
for(int i=1;i<n;i++)
{
cin>>x>>y;
sadd(x,y);
sadd(y,x);
}
// cout<<kk<<endl;
//return 0;
dfs(r,0);
dfs2(r,r);
build(1,1,n);
for(int i=1;i<=m;i++)
{
cin>>k;
if(k==1)
{
cin>>x>>y>>z;
qadd(x,y,z);
}
if(k==2)
{
cin>>x>>y;
cout<<qsum(x,y)<<endl;
}
if(k==3)
{
cin>>x>>z;
qson(x,z);
}
if(k==4)
{
cin>>x;
cout<<qqqsum(x)<<endl;
}
}
exit(0);
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...