求助树剖,10分,AC#4
查看原帖
求助树剖,10分,AC#4
579702
IANYEYZ楼主2022/7/10 17:46

rt

#include<iostream>
#include<vector>
#define int long long
#define pushup(p) tree[p] = tree[p*2]+tree[p*2+1]
using namespace std;
int tree[1000010],mark[1000010],a[1000010],dfn[1000010],rk[1000010],fa[1000010],son[1000010],deep[1000010],top[1000010],sz[1000010],n,m,r,p1,opt,x,y,z,k,cur;
vector<int> E[1000010];
void pushdown(int p,int l,int r)
{
	mark[p*2]+=mark[p];
	mark[p*2+1]+=mark[p];
	tree[p*2]+=mark[p]*((l+r)/2*1ll-l+1);
	tree[p*2]%=p1;
	tree[p*2+1]+=mark[p]*(r-(l+r)/2*1ll);
	tree[p*2+1]%=p1;
	mark[p] = 0; 
}
void build(int l,int r,int p)
{
	if(l == r)	tree[p] = a[rk[l]];
	else
	{
		build(l,(l+r)/2*1ll,p*2);
		build(((l+r)/2+1)*1ll,r,p*2+1);
		pushup(p);
	}
}
void add(int l,int r,int cl,int cr,int p,int d)
{
	if(l > cr||r < cl)	return;
	else if(l >= cl&&r <= cr)
	{
		tree[p]+=d*(r-l+1);
		tree[p]%=p1;
		mark[p]+=d;
	}
	else
	{
		pushdown(p,l,r);
		add(l,(l+r)/2*1ll,cl,cr,p*2,d);
		add(((l+r)/2+1)*1ll,r,cl,cr,p*2+1,d);
		pushup(p);
	}
}
int query(int l,int r,int cl,int cr,int p)
{
	if(l > cr||r < cl)	return 0;
	else if(l >= cl&&r <= cr)
	{
		return tree[p]%p1;
	}
	else
	{
		pushdown(p,l,r);
		return query(l,(l+r)/2*1ll,cl,cr,p*2)%p1+query(((l+r)/2+1)*1ll,r,cl,cr,p*2+1)%p1;
	}
}
void dfs1(int now)
{
	dfn[now] = ++cur;
	rk[cur] = now;
	deep[now] = deep[fa[now]]+1;
	sz[now]++;
	for(auto v:E[now])
	{
		if(v == fa[now])
		{
			continue;
		}
		fa[v] = now;
		dfs1(v);
		sz[now]+=sz[v];
		if(!son[now]||sz[v] > sz[son[now]])
		{
			son[now] = v;
		}
	}
}
void dfs2(int now,int tv)
{
	top[now] = tv;
	if(son[now])
	{
		dfs2(son[now],tv);
	}
	for(auto v:E[now])
	{
		if(v == son[now]||v == fa[now])
		{
			continue;
		}
		dfs2(v,v);
	}
}
void modifyontree(int u,int v,int d)
{
	while(top[u] != top[v])
	{
		if(deep[top[u]] < deep[top[v]])
		{
			swap(u,v);
		}
		add(1,n,dfn[top[u]],dfn[u],1,d);
		u = fa[top[u]];
	}
	if(deep[u] > deep[v])
	{
		swap(u,v);
	}
	add(1,n,dfn[u],dfn[v],1,d);
}
int queryontree(int u,int v)
{
	int ret = 0;
	while(top[u] != top[v])
	{
		if(deep[top[u]] < deep[top[v]])
		{
			swap(u,v);
		}
		ret+=query(1,n,dfn[top[u]],dfn[u],1);
		ret%=p1;
		u = fa[top[u]];
	}
	if(deep[u] > deep[v])
	{
		swap(u,v);
	}
	ret+=query(1,n,dfn[u],dfn[v],1);
	ret%=p1;
	return ret;
}
#undef int
int main()
{
	cin>>n>>m>>r>>p1;
	for(int i = 1;i <= n;i++)
	{
		cin>>a[i];
	}
	for(int i = 1;i <= n-1;i++)
	{
		cin>>x>>y;
		E[x].push_back(y);
		E[y].push_back(x);
	}
	dfs1(r);
	dfs2(r,r);
	build(1,n,1);
	for(int i = 1;i <= m;i++)
	{
		cin>>opt;
		if(opt == 1)
		{
			cin>>x>>y>>z;
			modifyontree(x,y,z);
		}
		else if(opt == 2)
		{
			cin>>x>>y;
			cout<<queryontree(x,y)%p1;
		}
		else if(opt == 3)
		{
			cin>>x>>z;
			add(1,n,dfn[x],dfn[x]+sz[x]-1,1,z);
		}
		else if(opt == 4)
		{
			cin>>x;
			cout<<query(1,n,dfn[x],dfn[x]+sz[x]-1,1)%p1<<endl;
		}
	}
}
2022/7/10 17:46
加载中...