萌新求助树剖,谢谢
查看原帖
萌新求助树剖,谢谢
191868
monstersqwq楼主2020/10/31 12:14
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
int n,m,s,mod;
int nxt[200005],hed[100005],to[100005],a[100005];
int cnt=0;
int c[4][100005];
void adde(int u,int v)
{
	cnt++;
	to[cnt]=v;
	nxt[cnt]=hed[u];
	hed[u]=cnt;
}
int lowbit(int x) {return x&-x;}
void upd(int x,int kin,int k)
{
	while(x<=n)
	{
		c[kin][x]=(c[kin][x]+k+5*mod)%mod;
		x+=lowbit(x);
	}
}
int query(int kin,int x)
{
	int res=0;
	while(x>=1)
	{
		res=(c[kin][x]+res+mod*5)%mod;
		x-=lowbit(x);
	}
	return (res+5*mod)%mod;
}
void update(int x,int y,int z)
{
	z%=mod;
	upd(x,1,z);
	upd(x,2,(z*x)%mod);
	upd(y+1,1,-z);
	upd(y+1,2,-(z*(y+1)%mod));
}
int ask(int x,int y)
{
	return (((y+1)*query(1,y)%mod-query(2,y))-(x*query(1,x-1)%mod-query(2,x-1))+5*mod)%mod;
}
//BIT 结束 
int dfscnt;
int f[100005],dth[100005],siz[100005],id[100005],son[100005],top[100005],rk[100005];
void dfs1(int u,int fa,int dep)
{
	f[u]=fa;
	dth[u]=dep;
	siz[u]=1;
	for(int i=hed[u];i!=0;i=nxt[i])
	{
		int v=to[i];
		if(v==f[u]) continue;
		dfs1(v,u,dep+1);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int tp)
{
	dfscnt++;
	id[u]=dfscnt;
	rk[dfscnt]=u;
	top[u]=tp;
	if(son[u]!=0) dfs2(son[u],tp);
	for(int i=hed[u];i!=0;i=nxt[i])
	{
		int v=to[i];
		if(v!=son[u]&&v!=f[u])
		{
			dfs2(v,v);
		}
	}
}
int main()
{
	cin>>n>>m>>s>>mod;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		adde(u,v);
		adde(v,u);
	}
	dfs1(s,0,1);
    dfs2(s,s);
    for(int i=1;i<=n;i++)
	{
        update(id[i],id[i],a[i]);
	}
    for(int i=1;i<=m;i++)
	{
		int opt;
		cin>>opt;
		if(opt==3)
		{
			int x,z;
			cin>>x>>z;
			update(id[x],id[x]+siz[x]-1,z);
		}
		if(opt==4)
		{
			int x;
			cin>>x;
			cout<<ask(id[x],id[x]+siz[x]-1)<<endl;
		}
        if(opt==1)
		{
			int x,y,z;
			cin>>x>>y>>z;
			int fx=top[x],fy=top[y];
			while(fx!=fy)
			{
				if(dth[fx]>=dth[fy])
				{
					update(id[fx],id[x],z);
					x=f[fx];
					fx=top[x];
				}
				else
				{
					update(id[fy],id[y],z);
					y=f[fy];
					fy=top[y];
				}
			}
			if(id[x]<=id[y])
			{
				update(id[x],id[y],z);
			}
			else
			{
				update(id[y],id[x],z);
			}
		}
		if(opt==2)
		{
			int ans=0,x,y;
            cin>>x>>y;
			int fx=top[x],fy=top[y];
			while(fx!=fy)
			{
				if(dth[fx]>=dth[fy])
				{
					ans=(ans+ask(id[fx],id[x]))%mod;
					x=f[fx];
					fx=top[x];
				}
				else
				{
					ans=(ans+ask(id[fy],id[y]))%mod;
					y=f[fy];
					fy=top[y];
				}
			}
			if(id[x]>=id[y]) ans=(ans+ask(id[y],id[x]))%mod;
			else ans=(ans+ask(id[x],id[y]))%mod;
			cout<<ans%mod<<endl;
		}
	}
	return 0;
}

WA了2 9 10,貌似是三个数据比较大的点,怀疑是爆int了或者取模爆炸了,求大佬们康康qaq

区间加区间求和是用的树状数组,应该没写错(吧

2020/10/31 12:14
加载中...