求问,为什么我的程序会MLE?
查看原帖
求问,为什么我的程序会MLE?
566363
GY程袁浩楼主2024/7/22 15:04
//简单一点点了......
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
struct node {
	int l, r, sum, lz;
	#define l(x) tr[x].l
	#define r(x) tr[x].r
	#define sum(x) tr[x].sum
	#define lz(x) tr[x].lz
}tr[N * 4];
int n, m, r, p;
int h[N], e[N], ne[N], w[N], wt[N], idx;
int son[N], id[N], fa[N], tsize[N], dep[N], top[N], cnt;//线段树上请用id
void add(int a, int b) {
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx++;
}
void pushup(int x) { sum(x) = (sum(x * 2) + sum(x * 2 + 1)) % p; }
void build(int x, int l, int r) {
	l(x) = l, r(x) = r;
	if (l == r) {
		sum(x) = wt[l] % p;
		return;
	}
	int mid = l + r >> 1;
	build(x * 2, l, mid), build(x * 2 + 1, mid + 1, r);
	pushup(x);
}
void pushdown(int x) {
	(lz(x * 2) += lz(x)) %= p;
	(lz(x * 2 + 1) += lz(x)) %= p;
	(sum(x * 2) += lz(x) * ((r(x * 2) - l(x * 2) + 1) % p) % p) %= p;
	(sum(x * 2 + 1) += lz(x) * ((r(x * 2 + 1) - l(x * 2 + 1) + 1) % p) % p) %= p;
	lz(x) = 0;
}
void change(int x, int ll, int rr, int k) {
	int l = l(x), r = r(x);
	if (l >= ll && r <= rr) {
		(sum(x) += (r - l + 1) % p * (k % p) % p) %= p;
		lz(x) += k;
		return;
	}
	pushdown(x);
	int mid = l + r >> 1;
	if (ll <= mid) change(x * 2, ll, rr, k);
	if (rr > mid) change(x * 2 + 1, ll, rr, k);
	pushup(x);
}
int qry(int x, int ll, int rr) {
	int l = l(x), r = r(x);
	if (l >= ll && r <= rr) return sum(x);
	pushdown(x);
	int mid = l + r >> 1, sum = 0;
	if (ll <= mid) sum += qry(x * 2, ll, rr);
	if (rr > mid) sum += qry(x * 2 + 1, ll, rr);
	pushup(x);
	return sum;
}
//板子,很快的线段树板子
int qryrange(int x, int y) {
	int ans = 0;
	while (top[x] != top[y]) {//不在同链
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		(ans += qry(1, id[top[x]], id[x]) % p) %= p;//上升!
		x = fa[top[x]];
	}//O(log n) 类似lca???
	if (dep[x] > dep[y]) swap(x, y);//注意从小到大
	return (ans+qry(1,id[x],id[y])%p)%p;
}
void updrange(int x, int y, int z) {
	z %= p;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		change(1, id[top[x]], id[x], z);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	change(1, id[x], id[y], z);
}
void updson(int x, int y) { change(1, id[x], id[x] + tsize[x] - 1, y); }
int qryson(int x) { return qry(1, id[x], id[x] + tsize[x] - 1); }
void dfs1(int x, int f, int deep) {
	dep[x] = deep;fa[x] = f;tsize[x] = 1;int maxn = -1;
	for (int i = h[x]; i != -1; i = ne[i]) {
		int j = e[i];
		if (j == f) continue;
		dfs1(j, x, deep + 1);
		tsize[x] += tsize[j];
		if (tsize[j] > maxn) maxn = tsize[j],son[x] = j;
	}
}
void dfs2(int x, int topf) {
	id[x] = ++cnt;wt[id[x]] = w[x];top[x] = topf;
	if (!son[x]) return;
	dfs2(son[x], topf);
	for (int i = h[x]; i != -1; i = ne[i]) {
		int j = e[i];
		if (j == fa[x] || j == son[x]) continue;
		dfs2(j, j);//新的链
	}
}
signed main() {
	memset(h, -1, sizeof h);cin >> n >> m >> r >> p;
	for (int i = 1; i <= n; i++) cin >> w[i];
	for (int i = 1; i <= n - 1; i++) {
		int x, y;cin >> x >> y;
		add(x, y), add(y, x);
	}
	dfs1(r, 0, 1);dfs2(r, r);build(1, 1, n);//剖分+建树
	for (int i = 1; i <= m; i++) {
		int c, x, y, z;
		cin >> c;
		if (c == 1) {
			cin >> x >> y >> z;
			updrange(x, y, z);
		}
		else if(c == 2) {
			cin >> x >> y;
			cout << qryrange(x, y) << endl;
		}
		else if (c == 3) {
			cin >> x >> y;
			updson(x, y);
		}
		else {
			cin >> x;
			cout << qryson(x) << endl;
		}
	}
	return 0;
}
2024/7/22 15:04
加载中...