社区讨论
树剖30分求助
P3384【模板】重链剖分 / 树链剖分参与者 4已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mi7csv0z
- 此快照首次捕获于
- 2025/11/20 19:34 4 个月前
- 此快照最后确认于
- 2025/11/20 19:34 4 个月前
AC 1 3 4 RE 2 5 6 7 10 WA 8 9
wa可能是取模的问题,但我查不出来,re是真的想不到哪里有问题
CPP#include<cstdio>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;
#define INF 2147483647
#define N 1000000007
long long n,m,r,p;
long long wy[100001]={0},mmap[200020][3]={0},last[100001]={0},js=2;//in
long long cs[100001]={0},pa[100001]={0},son[100001]={0},size[100001]={0},jjs=1;//dfs1
long long id[100001]={0},w[100001]={0},top[100001]={0};//dfs2
long long tree[800008]={0},lazy[800008]={0};//tree
void swap(long long &a,long long &b){a^=b;b^=a;a^=b;}
void add(long long x,long long y)
{
mmap[js][0]=x;
mmap[js][1]=y;
mmap[js][2]=last[x];
last[x]=js++;
}
void dfs1(long long x)
{
size[x]=1;
for(long long i=last[x];i;i=mmap[i][2])
{
if(cs[mmap[i][1]]) continue;
pa[mmap[i][1]]=x;
cs[mmap[i][1]]=cs[x]+1;
dfs1(mmap[i][1]);
if(size[mmap[i][1]]>size[son[x]]) son[x]=mmap[i][1];
size[x]+=size[mmap[i][1]];
}
}
void dfs2(long long x,long long topf)
{
id[x]=jjs++;
w[id[x]]=wy[x];
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(long long i=last[x];i;i=mmap[i][2])
{
if(id[mmap[i][1]]) continue;
dfs2(mmap[i][1],mmap[i][1]);
}
}
//---------------------------------------------------树上操作
void build(long long x,long long l,long long r)
{
if(l==r)
{
tree[x]=w[l];
return ;
}
long long m=(l+r)>>1;
build(x<<1,l,m);build(x<<1|1,m+1,r);
tree[x]=(tree[x<<1]+tree[x<<1|1])%p;//
}
void pushdown(long long x,long long l,long long r)
{
long long m=(l+r)>>1;
tree[x<<1]+=(m-l+1)*lazy[x];tree[x<<1]%=p;//
tree[x<<1|1]+=(r-m)*lazy[x];tree[x<<1|1]%=p;//
if(m-l+1) lazy[x<<1]+=lazy[x];lazy[x<<1]%=p;//
if(r-m) lazy[x<<1|1]+=lazy[x];lazy[x<<1|1]%=p;//
lazy[x]=0;
}
void treeadd(long long x,long long l,long long r,long long v,long long ll,long long rr)
{
tree[x]+=(min(rr,r)-max(ll,l)+1)*v;tree[x]%=p;//
if(ll<=l&&r<=rr)
{
if(l-r) lazy[x]+=v;
return ;
}
if(lazy[x]) pushdown(x,l,r);
long long m=(l+r)>>1;
if(m>=ll) treeadd(x<<1,l,m,v,ll,rr);
if(rr>m) treeadd(x<<1|1,m+1,r,v,ll,rr);
}
long long treecx(long long x,long long l,long long r,long long ll,long long rr)
{
if(ll<=l&&r<=rr) return tree[x];
if(lazy[x]) pushdown(x,l,r);
long long m=(l+r)>>1;
long long c=0;
if(m>=ll) c+=treecx(x<<1,l,m,ll,rr);
if(rr>m) c+=treecx(x<<1|1,m+1,r,ll,rr);
return c%p;//
}
//---------------------------------------------------树上操作
//---------------------------------------------------操作
void xgl()
{
long long x,y,v;
scanf("%lld%lld%lld",&x,&y,&v);
while(top[id[x]]!=top[y])
{
if(cs[top[x]]<cs[top[y]]) swap(x,y);
treeadd(1,1,n,v,id[x],id[top[x]]);
x=pa[top[x]];
}
if(cs[x]>cs[y]) swap(x,y);
treeadd(1,1,n,v,id[x],id[y]);
}
void suml()
{
long long x,y,sum=0;
scanf("%lld%lld",&x,&y);
while(top[x]!=top[y])
{
if(cs[top[x]]<cs[top[y]]) swap(x,y);
sum+=treecx(1,1,n,id[x],id[top[x]]);
x=pa[top[x]];
}
if(cs[x]>cs[y]) swap(x,y);
sum+=treecx(1,1,n,id[x],id[y]);
printf("%lld\n",sum);
}
void xg()
{
long long x,v;
scanf("%lld%lld",&x,&v);
treeadd(1,1,n,v,id[x],id[x]+size[x]-1);
}
void sum()
{
long long x;
scanf("%lld",&x);
printf("%lld\n",treecx(1,1,n,id[x],id[x]+size[x]-1));
}
//---------------------------------------------------操作
int main()
{
cin>>n>>m>>r>>p;
for(int i=1;i<=n;i++) scanf("%lld",&wy[i]);
for(int i=1;i<n;i++)
{
long long a,b;
scanf("%lld%lld",&a,&b);
add(a,b);
add(b,a);
}
cs[r]=1;
dfs1(r);
dfs2(r,r);
build(1,1,n);
while(m--)
{
int a;
scanf("%d",&a);
if(a==1) xgl();
else if(a==2) suml();
else if(a==3) xg();
else if(a==4) sum();
}
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...