社区讨论

萌新刚学线段树合并,求助 36pts 的屑代码

P6773[NOI2020] 命运参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mhjt463r
此快照首次捕获于
2025/11/04 08:04
4 个月前
此快照最后确认于
2025/11/04 08:04
4 个月前
查看原帖
QAQ 主要是 TLE 了,应该是因为线段树合并斜挂了,但是确实不知道改怎么改。萌新刚学线段树合并,球球巨佬教教 qwq
CPP
#include <bits/stdc++.h>
#define il inline
#define ll long long
using namespace std;
const int N = 1e5;
const ll Mod = 998244353;
int n, m;
struct tg {
	ll add, mul;
};
struct node {
	int ls, rs;
	tg tag;
} T[N * 300 + 10];
namespace sgt {
	int tot = 0, rt[N + 10];
	vector <int> bin;
	il int newnode(int add, int mul) {
		int now = 0;
		if(bin.size()) now = bin[bin.size() - 1], bin.pop_back();
		else now = ++tot;
//		now = ++tot; 
		T[now].ls = T[now].rs = 0;
		T[now].tag.add = add, T[now].tag.mul = mul;
		return now;
	}
	il void push_tag(int now, tg tag) {
		T[now].tag.add = (T[now].tag.add * tag.mul + tag.add) % Mod;
		T[now].tag.mul = T[now].tag.mul * tag.mul % Mod;
	}
	il void push_down(int now) {
		if(T[now].tag.add != 0 || T[now].tag.mul != 1) {
			if(!T[now].ls) T[now].ls = newnode(0, 0);
			if(!T[now].rs) T[now].rs = newnode(0, 0);
			push_tag(T[now].ls, T[now].tag);
			push_tag(T[now].rs, T[now].tag);
			T[now].tag.add = 0;
			T[now].tag.mul = 1;
		}
	}
	
	il void clear(int u) {
		bin.push_back(u);
		if(T[u].ls) clear(T[u].ls);
		if(T[u].rs) clear(T[u].rs);
	}
	il int upd(int ql, int qr, int s, int t, int now, tg tag) {
		if(ql <= s && t <= qr) {
			push_tag(now, tag);
			return now;
		}
		int mid = (s + t) >> 1;
		push_down(now);
		if(ql <= mid) T[now].ls = upd(ql, qr, s, mid, T[now].ls, tag);
		if(qr > mid) T[now].rs = upd(ql, qr, mid + 1, t, T[now].rs, tag);
		return now;
	}
	il ll qry(int pos, int s, int t, int now) {
		if(s == t) return T[now].tag.add;
		int mid = (s + t) >> 1;
		push_down(now);
		if(pos <= mid) return qry(pos, s, mid, T[now].ls);
		else return qry(pos, mid + 1, t, T[now].rs);
	}
	il int merge(int l, int r, int x, int y) {
		if(!x || !y) return x + y;
		if(l == r) {
			push_tag(x, (tg){0, T[y].tag.add});
			return x;
		}
		int mid = (l + r) >> 1;
		push_down(x);
		push_down(y);
		T[x].ls = merge(l, mid, T[x].ls, T[y].ls);
		T[x].rs = merge(mid + 1, r, T[x].rs, T[y].rs);
		return x;
	}
}
vector <int> gra[N + 10];
int dep[N + 10], up[N + 10];
void predfs(int u, int fa) {
	dep[u] = dep[fa] + 1;
	for(int i = 0; i < gra[u].size(); i++) {
		int v = gra[u][i];
		if(v == fa) continue;
		predfs(v, u);
	}
}
void dp(int u, int fa) {
	up[u] = max(up[u], up[fa]);
	for(int i = 0; i < gra[u].size(); i++) {
		int v = gra[u][i];
		if(v == fa) continue;
		dp(v, u);
	}
	
//	if(gra[u].size() == 1) cout << up[u] << ' ' << dep[u] << endl;
	sgt::rt[u] = sgt::newnode(0, 0);
	sgt::upd(up[u], dep[u] - 1, 0, n, sgt::rt[u], (tg){1, 1});
	for(int i = 0; i < gra[u].size(); i++) {
		int v = gra[u][i];
		if(v == fa) continue;
		ll rest = sgt::qry(dep[u], 0, n, sgt::rt[v]);
//		cout << v << ' ' << rest << ":"; 
		sgt::upd(0, dep[u], 0, n, sgt::rt[v], (tg){rest, 1});
//		for(int j = 0; j <= n; j++)
//			cout << sgt::qry(j, 0, n, sgt::rt[v]) << ' ';
//		cout << endl;
		sgt::merge(0, n, sgt::rt[u], sgt::rt[v]);
		sgt::clear(sgt::rt[v]);
	}
	
//	if(u == 1) return ;
//	cout << u << ' ' << up[u] << ' ' << dep[u] << ":";
//	for(int i = 0; i <= n; i++)
//		cout << sgt::qry(i, 0, n, sgt::rt[u]) << ' ';
//	cout << endl;
//	ll rest = sgt::qry(dep[u] - 1, 0, n, sgt::rt[u]);
//	sgt::upd(0, dep[u], 0, n, sgt::rt[u], (tg){rest, 1});
	
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for(int i = 1, x, y; i < n; i++) {
		cin >> x >> y;
		gra[x].push_back(y);
		gra[y].push_back(x);
	}
	predfs(1, 0);
	
	cin >> m;
	for(int i = 1, x, y; i <= m; i++) {
		cin >> x >> y;
		up[y] = max(up[y], dep[x]);
	}
	
	dp(1, 0);
	cout << sgt::qry(0, 0, n, sgt::rt[1]) << endl;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...