社区讨论

树剖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 条回复,欢迎继续交流。

正在加载回复...