_AyachiNene @ 2023-05-10 20:43:57
#include<bits/stdc++.h>
#define maxn 114514
#define ls root*2
#define rs root*2+1
using namespace std;
struct node
{
int nxt,to;
}e[maxn*2];
//----------线段树-------------------
int k;
int n,m,r,p;
struct node1
{
int l,r,val,f;
}t[maxn*4];
void bld(int l,int r,int root)
{
t[root].l=l;
t[root].r=r;
if(l==r)
{
cin>>t[root].val;
t[root].val%=p;
return;
}
int mid=(l+r)/2;
bld(l,mid,root*2);
bld(mid+1,r,root*2+1);
t[root].val=(t[ls].val+t[rs].val)%p;
}
void down(int root)
{
t[ls].f+=t[root].f;
t[rs].f+=t[root].f;
t[ls].val=(t[ls].val+(t[ls].r-t[ls].l+1)*t[root].f)%p;
t[rs].val=(t[rs].val+(t[rs].r-t[rs].l+1)*t[root].f)%p;
t[root].f=0;
}
void add2(int x,int y,int root,int k)
{
if(t[root].l>=x&&t[root].r<=y)
{
t[root].val+=((t[root].r-t[root].l+1)*k)%p;
t[root].f+=k;
return;
}
if(t[root].f)
down(root);
int mid=(t[root].l+t[root].r)/2;
if(x<=mid)
add2(x,y,root*2,k);
if(y>mid)
add2(x,y,root*2+1,k);
t[root].val=(t[ls].val+t[rs].val)%p;
}
int query(int x,int y,int root)
{
int ret=0;
if(t[root].l>=x&&t[root].r<=y)
return t[root].val;
if(t[root].f)
down(root);
int mid=(t[root].l+t[root].r)/2;
if(x<=mid)
ret=(ret+query(x,y,ls))%p;
if(y>mid)
ret=(ret+query(x,y,rs))%p;
return ret;
}
//-----------------------------------
int head[maxn*2],cnt1;
void add(int u,int v)
{
e[++cnt1].to=v;
e[cnt1].nxt=head[u];
head[u]=cnt1;
}
int top[maxn],dfn[maxn],rk[maxn],son[maxn],size[maxn],f[maxn],dep[maxn],cnt;
void dfs1(int u,int fa)
{
size[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=fa)
{
dep[v]=dep[u]+1;
f[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int t)
{
dfn[++cnt]=u;
top[u]=t;
if(son[u])
dfs2(son[u],t);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=f[u]&&v!=son[u])
dfs2(v,v);
}
}
int sum(int x,int y)
{
int ans=0,fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]<dep[fy])
swap(x,y),swap(fx,fy);
ans+=query(dfn[fx],dfn[x],1);;
x=f[fx],fx=top[x];
}
if(dfn[x]>dfn[y])
swap(x,y);
ans+=query(dfn[x],dfn[y],1);
return ans;
}
void add1(int x,int y,int z)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]<dep[fy])
swap(x,y),swap(fx,fy);
add2(dfn[fx],dfn[x],1,z);
x=f[fx],fx=top[x];
}
if(dfn[x]>dfn[y])
swap(x,y);
add2(dfn[x],dfn[y],1,z);
}
int main()
{
cin>>n>>m>>r>>p;
bld(1,n,1);
for(int i=1;i<n;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(r,0);
dfs2(r,r);
while(m--)
{
int op,x,y,z;
cin>>op;
if(op==1)
{
cin>>x>>y>>z;
add1(x,y,z);
}
else if(op==2)
{
cin>>x>>y;
k=0;
cout<<sum(x,y)<<endl;
}
else if(op==3)
{
cin>>x>>z;
add2(dfn[x],dfn[x]+size[x]-1,1,z);
}
else
{
cin>>x;
cout<<query(dfn[x],dfn[x]+size[x]-1,1)<<endl;
}
}
// for(int i=1;i<=10;i++)
// cout<<t[i].val<<' ';
}
by hegm @ 2023-05-11 15:33:50
@brother_jie 6
by hegm @ 2023-05-11 15:34:22
你还没剖分就读入权值?
by hegm @ 2023-05-11 15:36:46
过了就给个关注吧
by _AyachiNene @ 2023-05-11 22:10:04
@hegm dalao还是10pts啊(悲
#include<bits/stdc++.h>
#define maxn 114514
#define ls root*2
#define rs root*2+1
using namespace std;
struct node
{
int nxt,to;
}e[maxn*2];
//----------线段树-------------------
int n,m,r,p,a[maxn],w[maxn];
struct node1
{
int l,r,val,f;
}t[maxn*4];
void bld(int l,int r,int root)
{
t[root].l=l;
t[root].r=r;
if(l==r)
{
t[root].val=w[l];
t[root].val%=p;
return;
}
int mid=(l+r)/2;
bld(l,mid,root*2);
bld(mid+1,r,root*2+1);
t[root].val=(t[ls].val+t[rs].val)%p;
}
void down(int root)
{
t[ls].f+=t[root].f;
t[rs].f+=t[root].f;
t[ls].val=(t[ls].val+(t[ls].r-t[ls].l+1)*t[root].f)%p;
t[rs].val=(t[rs].val+(t[rs].r-t[rs].l+1)*t[root].f)%p;
t[root].f=0;
}
void add2(int x,int y,int root,int k)
{
if(t[root].l>=x&&t[root].r<=y)
{
t[root].val+=((t[root].r-t[root].l+1)*k)%p;
t[root].f+=k;
return;
}
if(t[root].f)
down(root);
int mid=(t[root].l+t[root].r)/2;
if(x<=mid)
add2(x,y,ls,k);
if(y>mid)
add2(x,y,rs,k);
t[root].val=(t[ls].val+t[rs].val)%p;
}
int query(int x,int y,int root)
{
int ret=0;
if(t[root].l>=x&&t[root].r<=y)
return t[root].val;
if(t[root].f)
down(root);
int mid=(t[root].l+t[root].r)/2;
if(x<=mid)
ret=(ret+query(x,y,ls))%p;
if(y>mid)
ret=(ret+query(x,y,rs))%p;
return ret;
}
//-----------------------------------
int head[maxn*2],cnt1;
void add(int u,int v)
{
e[++cnt1].to=v;
e[cnt1].nxt=head[u];
head[u]=cnt1;
}
int top[maxn],dfn[maxn],son[maxn],size[maxn],f[maxn],dep[maxn],cnt;
void dfs1(int u,int fa)
{
size[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=fa)
{
dep[v]=dep[u]+1;
f[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int t)
{
dfn[++cnt]=u;
w[cnt]=a[u];
top[u]=t;
if(son[u])
dfs2(son[u],t);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=f[u]&&v!=son[u])
dfs2(v,v);
}
}
int sum(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
ans=(ans+query(dfn[top[x]],dfn[x],1))%p;
x=f[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ans=(ans+query(dfn[x],dfn[y],1))%p;
return ans;
}
void add1(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
add2(dfn[top[x]],dfn[x],1,z);
x=f[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
add2(dfn[x],dfn[y],1,z);
}
int main()
{
cin>>n>>m>>r>>p;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<n;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(r,0);
dfs2(r,r);
bld(1,n,1);
while(m--)
{
int op,x,y,z;
cin>>op;
if(op==1)
{
cin>>x>>y>>z;
add1(x,y,z);
}
else if(op==2)
{
cin>>x>>y;
cout<<sum(x,y)<<endl;
}
else if(op==3)
{
cin>>x>>z;
add2(dfn[x],dfn[x]+size[x]-1,1,z);
}
else
{
cin>>x;
cout<<(query(dfn[x],dfn[x]+size[x]-1,1))%p<<endl;
}
}
}
by hegm @ 2023-05-12 06:57:06
@brother_jie 你。。。。。你要不重新学一下树剖?
by hegm @ 2023-05-12 07:00:31
树剖上线段树维护的
by _AyachiNene @ 2023-05-13 12:44:42
@hegm dalao我就是维护的编号啊
by _AyachiNene @ 2023-05-13 14:38:43
破案力,dfs2写错了
by _AyachiNene @ 2023-05-13 14:40:29
@hegm 已关注