求助,树链剖分哪里写挂了
查看原帖
求助,树链剖分哪里写挂了
42760
⊱⋛赫宇⋚⊰楼主2021/8/13 19:05
#include<bits/stdc++.h>
#define ls(x) x<<1
#define rs(x) x<<1|1
#define I inline
#define LL long long
#define RI register int 
#define maxn 100010
using namespace std;
I int read()
{
	RI res=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch)){res=(res<<1)+(res<<3)+(ch&15);ch=getchar();}
	return res*f;
}
struct Tree{
	int l,r;
	LL sum;
}tree[maxn*4];
LL lazy[maxn*4];
int n,m,root;LL mod;
int val[maxn],a[maxn];
int head[maxn],tot;
struct node{
	int to,next;
}edge[maxn*2];
I void add(int x,int y)
{
	edge[++tot].to=y;
	edge[tot].next=head[x];
	head[x]=tot;
}
int deep[maxn],son[maxn],top[maxn],id[maxn],size[maxn],f[maxn];
int cnt;
I void build(int l,int r,int id)
{
	tree[id].l=l;tree[id].r=r;
	if(l==r){tree[id].sum=a[l];return ;}
	int mid=(l+r)>>1;
	build(l,mid,ls(id));
	build(mid+1,r,rs(id));
	tree[id].sum=(tree[ls(id)].sum+tree[rs(id)].sum)%mod;
	return;
}
I void pushdown(int x)
{
	if(!lazy[x])return;
	tree[ls(x)].sum=(tree[ls(x)].sum+(tree[ls(x)].r-tree[ls(x)].l+1)*lazy[x])%mod;
	tree[rs(x)].sum=(tree[rs(x)].sum+(tree[rs(x)].r-tree[rs(x)].l+1)*lazy[x])%mod;
	lazy[ls(x)]=(lazy[ls(x)]+lazy[x])%mod;
	lazy[rs(x)]=(lazy[rs(x)]+lazy[x])%mod;
	lazy[x]=0;
	return ;
}
I void change(int l,int r,LL k,int id)
{
	if(tree[id].l>=l&&tree[id].r<=r)
	{
		lazy[id]=(lazy[id]+k)%mod;
		tree[id].sum=(tree[id].sum+(tree[id].r-tree[id].l+1)*k)%mod;
		return;
	}
	pushdown(id);
	if(tree[ls(id)].r>=l)change(l,r,k,ls(id));
	if(tree[rs(id)].l<=r)change(l,r,k,rs(id));
	tree[id].sum=(tree[ls(id)].sum+tree[rs(id)].sum)%mod;
	return;
}
I LL getsum(int l,int r,int id)
{
	if(tree[id].l>=l&&tree[id].r<=r)return tree[id].sum;
	pushdown(id);
	LL ans=0;
	if(tree[ls(id)].r>=l)ans+=getsum(l,r,ls(id)),ans%=mod;
	if(tree[rs(id)].l<=r)ans+=getsum(l,r,rs(id)),ans%=mod;
	return ans;
}
I void dfs1(int x,int fa)
{
	f[x]=fa;
	size[x]=1;
	deep[x]=deep[fa]+1;
	int maxson=-1;
	for(RI i=head[x];i;i=edge[i].next)
	{
		int to=edge[i].to;
		if(to==fa)continue;
		dfs1(to,x);
		size[x]+=size[to];
		if(size[to]>maxson)maxson=size[to],son[x]=to;
	}
}
I void dfs2(int x,int tp)
{
	id[x]=++cnt;
	a[cnt]=val[x];
    top[x]=tp;
    if(!son[x])return;
    dfs2(son[x],tp);
    for(RI i=head[x];i;i=edge[i].next)
    {
    	int to=edge[i].to;
    	if(to==f[x]||to==son[x])continue;
    	dfs2(to,to);
	}
}
I LL ask(int x,int y)
{
	LL ans=0;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        ans+=getsum(id[ top[x] ],id[x],1);
        ans%=mod;
        x=f[ top[x] ];
    }
    if(deep[x]>deep[y])   swap(x,y);
    ans+=getsum(id[x],id[y],1);
    ans%=mod;
    return ans;
}
int main()
{
	n=read();m=read();root=read();mod=read();
	for(RI i=1;i<=n;i++)val[i]=read();
	for(RI i=1;i<n;i++)
	{
		int u,v;u=read();v=read();
		add(u,v);add(v,u);
	 } 
	dfs1(root,0);
	dfs2(root,root);
	build(1,n,1);
	while(m--)
	{
		int op;
		op=read();
		if(op==1)
		{
			int x,y;LL z;x=read();y=read();cin>>z;
			change(x,y,z,1);
		}
		else
		{
			if(op==2)
			{
			  int x,y;x=read();y=read();
			  printf("%lld\n",ask(x,y));	
		    }
		    else
		    {
		    	if(op==3)
		    	{
		    		int x;LL z;
		    		x=read();cin>>z; 
		    		change(id[x],id[x]+size[x]-1,z,1);
				}
				else
				{
					int x;
					x=read();
					printf("%lld\n",getsum(id[x],id[x]+size[x]-1,1));
				}
			}
		 } 
	}
	return 0;
}
2021/8/13 19:05
加载中...