蒟蒻37pts,求调树剖
查看原帖
蒟蒻37pts,求调树剖
800703
xxxxxxxb楼主2023/8/30 13:23

只过了#1#2#3#11,应该不是取模的问题

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = (int)1e5+7;
int n,m,r,MOD,a[N],fa[N],dfn[N],dep[N],siz[N],son[N],top[N],rks[N],cnt,bot[N];
std::vector<int> e[N];
void dfs_fi(int u,int depth) {
	dep[u] = depth,siz[u] = 1;
	for(auto v : e[u]) {
		if(!dep[v]) {
			fa[v] = u;
			dfs_fi(v,depth+1);
			siz[u] += siz[v];
			son[u] = siz[son[u]] < siz[v] ? v : son[u];
		}
	}
} 
void dfs_se(int u,int t) {
	dfn[u] = ++cnt,top[u] = t;
	rks[cnt] = u;
	if(!son[u]) {
		bot[u] = cnt;
		return;
	}
	dfs_se(son[u],t);
	for(auto v : e[u]) {
		if(v!=fa[u]&&v!=son[u]) dfs_se(v,v);
	}
	bot[u] = cnt;
}
struct Segment_Tree {
	int d[N<<2],b[N<<2];
	int lson(int p) {return p << 1;}
	int rson(int p) {return p << 1 | 1;}
	int gm(int s,int t) {return (s+t)>>1;}
	void pushup(int p) {
		d[p] = (1ll*d[lson(p)]%MOD + d[rson(p)]%MOD)%MOD;
	}
	void pushd(int s,int t,int p) {
		int m = gm(s,t);
		if(b[p]) {
			d[lson(p)] = (1ll*d[lson(p)]%MOD + 1ll*(m-s+1)*b[p]%MOD)%MOD;
			d[rson(p)] = (1ll*d[rson(p)]%MOD + 1ll*(t-m)*b[p]%MOD)%MOD;
			b[lson(p)] = (1ll*b[lson(p)]%MOD + 1ll*b[p]%MOD) % MOD;
			b[rson(p)] = (1ll*b[rson(p)]%MOD + 1ll*b[p]%MOD) % MOD;
			b[p] = 0;
		}
	}
	void build(int s,int t,int p) {
		if(s==t) {
			d[p] = a[rks[s]];
			return;
		}
		int m = gm(s,t);
		build(s,m,lson(p));
		build(m+1,t,rson(p));
		pushup(p);
	}
	void upt(int s,int t,int p,int l,int r,int k) {
		if(l<=s&&t<=r) {
			d[p] = (1ll*d[p] + 1ll*(t-s+1)*k%MOD)%MOD;
			b[p] = (1ll*b[p] + k%MOD) % MOD;
			return;
		}
		int m = gm(s,t);
		pushd(s,t,p);
		if(l <= m) upt(s,m,lson(p),l,r,k);
		if(r > m) upt(m+1,t,rson(p),l,r,k);
		pushup(p);
	}
	int query(int s,int t,int p,int l,int r) {
		if(l <= s&&t <= r) {
			return d[p];
		}
		int m = gm(s,t),res = 0;
		pushd(s,t,p);
		if(l <= m) res = (1ll*res%MOD + query(s,m,lson(p),l,r)%MOD) % MOD;
		if(r > m)  res = (1ll*res%MOD + query(m+1,t,rson(p),l,r)%MOD) % MOD;
		return res;
	}
} tree;
auto que(int s,int t) -> int {
	int res = 0;
	while(top[s] != top[t]) {
		if(dep[top[s]] < dep[top[t]]) swap(s,t);
		res = (1ll*res%MOD + 1ll*tree.query(1,n,1,dfn[s],dfn[top[s]])%MOD)%MOD;
		s = fa[top[s]];
	}
	if(dep[s] > dep[t]) swap(s,t);
	res = (1ll*res%MOD + 1ll*tree.query(1,n,1,dfn[s],dfn[t])%MOD) % MOD;
	return res%MOD;
}
auto add(int s,int t,int k) -> void {
	while(top[s] != top[t]) {
		if(dep[top[s]] < dep[top[t]]) swap(s,t);
		tree.upt(1,n,1,dfn[s],dfn[top[s]],k);
		s = fa[top[s]];
	}
	if(dep[s] > dep[t]) swap(s,t);
	tree.upt(1,n,1,dfn[s],dfn[t],k);
}
void sol() {
	int opt;
	cin >> opt;
	if(opt == 1) {
		int x,y,z;
		cin >> x >> y >> z;
		add(x,y,z%MOD);
	} else if(opt == 2) {
		int x,y;
		cin >> x >> y;
		cout << que(x,y)%MOD << "\n";
	} else if(opt == 3) {
		int x,z;
		cin >> x >> z;
		tree.upt(1,n,1,dfn[x],dfn[x]+siz[x]-1,z);
	} else {
		int x;
		cin >> x;
		cout << tree.query(1,n,1,dfn[x],dfn[x]+siz[x]-1)%MOD << "\n";
	}
}
signed main() {
	//freopen("P3384_4.in","r",stdin);
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m >> r >> MOD;
    for(int i = 1;i <= n;++i) {
    	cin >> a[i];
    }
    for(int i = 1;i <= n-1;++i) {
    	int u,v;
    	cin >> u >> v;
    	e[u].push_back(v),e[v].push_back(u);
    }
    dfs_fi(r,1);
    dfs_se(r,r);
    tree.build(1,n,1);
    while(m--) {
    	sol();
    }
    return 0;
}
2023/8/30 13:23
加载中...