wa 30,实在调不出来了
查看原帖
wa 30,实在调不出来了
574945
SCAU_anpuren楼主2022/6/30 16:52
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<map>
#include<utility>
#include<queue>
#include<set>
#include<vector>
#include<unordered_set>;
using namespace std;
typedef long long ll;
#define endl '\n';
struct node
{
	ll u, v, next;
}edge[5000005];
ll cnt = 0;
ll head[5000005];
void add(ll u, ll v)
{
	edge[cnt].u = u;
	edge[cnt].v = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
ll a[5000005];
ll fa[5000005];//记录某个点的父情节点
ll top[5005005];//记录某个点的所在重链的顶点
ll num[5005005];//记录某个点的节点数
ll son[5005005];//记录某个点的重儿子
ll dep[5000505];//深度
#define _for(i,a) for(ll i=1;i<=a;i++);
ll n, m, r, mod;//节点数量,操作次数,更节点,取模
void dfs1(ll u, ll f)
{
	fa[u] = f;
	num[u] = 1;
	dep[u] = dep[f] + 1;
	for (int i = head[u]; i + 1; i = edge[i].next)
	{
		ll v = edge[i].v;
		if (v == f)continue;
		dfs1(v, u);
		num[u] += num[v];
		if (num[son[u]] < num[v])
		{
			son[u] = v;
		}
	}
}
ll id[5000005];//重新编号后的编号
ll newnum[5000005];//重新编号后值
ll tot = 0;
void dfs2(ll u, ll to)
{
	top[u] = to;
	id[u] = ++tot;
	newnum[id[u]] = a[u];
	//cout << u << " " << fa[u] << endl;
	if (!son[u])return;
	dfs2(son[u], to);
	for (int i = head[u]; i + 1; i = edge[i].next)
	{
		ll v = edge[i].v;
		if (v == fa[u] || v == son[u])continue;
		dfs2(v, v);
	}
}
struct node11
{
	ll l, r, lazy, sum;
}t[5000005];
void push_down(ll p)
{
	if (t[p].lazy) 
	{
		//cout << p << endl;
		ll xx = t[p].lazy;
		t[p].lazy = 0;
		t[p * 2].lazy =(t[p*2].lazy+ xx)%mod;
		t[p * 2 + 1].lazy =(t[p*2+1].lazy+ xx)%mod;
		t[p * 2 + 1].sum =(t[p*2+1].sum+ (((t[p * 2 + 1].r - t[p * 2 + 1].l + 1))%mod)*xx)%mod;
		t[p * 2].sum =(t[p*2].sum+ (((t[p * 2].r - t[p * 2].l + 1))%mod)*xx)%mod;
	}
}
void push_up(ll p)
{
	t[p].sum = (t[p * 2].sum + t[p * 2 + 1].sum)%mod;
}
ll query(ll p, ll l, ll r)
{
	if (t[p].l >= l && t[p].r <= r)
	{
		return t[p].sum%mod;
	}
	push_down(p); 
	ll res = 0;
	ll mid =( t[p].l+t[p].r)/2;
	if (mid >= l)res = (res+query(p * 2, l,r))%mod;
	if (mid<r)res = (res+query(p * 2 + 1, l, r))%mod;
	return res;
}
void build(ll p, ll l, ll r)
{
	t[p].l = l;
	t[p].r = r;
	if (l == r)
	{
		t[p].sum = newnum[l];
		return;
	}
	ll mid = (l + r) / 2;
	if (mid >= l)
	{
		build(p * 2, l, mid);
	}
	if (mid < r)
	{
		build(p * 2 + 1, mid + 1, r);
	}
	push_up(p);
}
void update(ll p, ll l, ll r,ll x)
{
	if (t[p].l >= l && t[p].r <= r)
	{
		t[p].sum =(t[p].sum+ ((t[p].r - t[p].l + 1)*x)%mod)%mod;
		t[p].lazy =(t[p].lazy +x)%mod;
		return;
	}
	push_down(p);
	ll mid = (t[p].l + t[p].r) / 2;
	if (mid >= l)
	update(p * 2, l, r,x);
	if (mid < r)
	update(p * 2 + 1, l, r, x);
	push_up(p);
}
void update_path(ll p,ll u,ll v,ll x)
{
	while (top[u] != top[v])
	{
		if (dep[top[u]] < dep[top[v]])swap(u, v);
		update(1, id[top[u]], id[u], x);
		u = fa[top[u]];
	//	cout << top[u] << " " << top[v] << endl;
	}
	if (dep[u] < top[v])swap(u, v);
	update(1, id[v], id[u], x);
}
ll query_path(ll p, ll u, ll v)
{
	ll res = 0;
	while (top[u] != top[v])
	{
		if (dep[top[u]] < dep[top[v]])swap(u, v);
		res = (res+query(1, id[top[u]], id[u]))%mod;
		u = fa[top[u]];
	}
	if (dep[u] < dep[v])swap(u, v);
	res = (res+query(1, id[v], id[u]))%mod;
	return res;
}
int  main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	memset(head, -1, sizeof(head));
	cin >> n >> m >> r >> mod;
	for (int i = 1; i <= n; i++) { cin >> a[i]; a[i] %= mod; }
	for (int i = 1; i < n; i++)
	{
		ll u, v;
		cin >> u >> v;
		add(u, v);
		add(v, u);
	}
	dfs1(r,r);
	dfs2(r,r);
	build(1, 1, n);
/*	for (int i = 1; i <= n; i++)
	{
		cout << i << " " << query(1, id[i], id[i]) << endl;
	}*/
	while (m--)
	{
		ll op;
		cin >> op;
		if (op == 1)
		{
			ll x, y, z;
			cin >> x >> y >> z;//x到y增加z
			update_path(1, x, y, z);
		}
		else  if(op==2)
		{
			ll x, y;
			cin >> x >> y;//查询x到y
			cout<<(query_path(1, x, y))%mod<<endl;
		}
		else if (op == 3)
		{
			ll x, y;
			cin >> x >> y;//以x为根节点都加上y
			update(1,id[x], id[x] + num[x] - 1, y);
		}
		else if (op == 4)
		{
			ll x;
			cin >> x;//以x为根节点的子树的和
			cout << (query(1,id[x], id[x] + num[x] - 1))%mod<<endl;
		}
		/*for (int i = 1; i <= n; i++)
		{
			cout << i << " " << query(1, id[i], id[i]) << endl;
		}*/
	}
}
2022/6/30 16:52
加载中...