70分求助!
查看原帖
70分求助!
433966
_Agony楼主2021/9/2 08:36

求解:#2 #9 #10 全部1.2sTLE,大佬帮帮小蒟蒻。

【code】

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int N = 2e6 + 5;

int n, m, s;
int num;
int cnt, mod;
int a[N], b[N], fa[N];//b是原数据, a是dfs序数据 
int idx[N], top[N];//idx是x的dfs序 
int son[N], tot[N];//重儿子, 重量 
int deep[N], head[N];

struct bal {
	int nxt;
	int to;
};
bal e[N<<1];

struct ball {
	int l, r;
	int sum;
	int size;
	int lazy;
};
ball t[N<<2];

int re() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0'||ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while (ch <= '9'&&ch >= '0') {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x * f;
}

void add(int u, int v) {
	++cnt;
	e[cnt].nxt = head[u];
	e[cnt].to = v;
	head[u] = cnt;
}

int dfs1(int x, int f, int dep) {//预处理 
	deep[x] = dep;
	tot[x] = 1; fa[x] = f;
	int maxson = -1;
	for(int i = head[x]; i; i = e[i].nxt) {
		int v = e[i].to;
		if(v == f) continue;
		tot[x] += dfs1(v, x, dep + 1);//回溯求重量 
		maxson = max(maxson, tot[v]);//维护x的重儿子 
	}
	son[x] = maxson;
	return tot[x];
}

void dfs2(int x, int ftop) {//找top 
	idx[x] = ++num;
	a[num] = b[x];
	top[x] = ftop;
	if(!son[x]) return;//到底了就返回 
	for(int i = head[x]; i; i = e[i].nxt) {
		int v = e[i].to;
		if(!idx[v]) dfs2(v, v);
	}
}

void update(int k) {
	t[k].sum = (t[k<<1].sum + t[k<<1|1].sum + mod) % mod;
}

void pushdown(int k) {
	if(!t[k].lazy) return ;
	t[k<<1].sum += (t[k<<1].size * t[k].lazy + mod) % mod;
	t[k<<1|1].sum += (t[k<<1|1].size * t[k].lazy + mod) % mod;
	t[k<<1].lazy += t[k].lazy;
	t[k<<1|1].lazy += t[k].lazy;
	t[k].lazy = 0;
}

void build(int p, int l, int r) {
	if(l < 0||r > n) return ;
	t[p].l = l; t[p].r = r;
	t[p].size = (r - l) + 1;
	if(l == r) {
		t[p].sum = a[l];
		return ;
	}
	int mid = (l + r) / 2;
	build(p * 2, l, mid);
	build(p * 2 + 1, mid + 1, r);
	update(p);
}

void Interval_addition(int p, int l, int r, int val) {//路径加 
	if(l <= t[p].l&&r >= t[p].r) {
		t[p].sum += (t[p].size * val + mod) % mod;
		t[p].lazy += val;
		return ;
	}
	pushdown(p);
	int mid = (t[p].l + t[p].r) >> 1;
	if(l <= mid) Interval_addition(p<<1, l, r, val);
	if(r > mid) Interval_addition(p<<1|1, l, r, val);
	update(p);
}

int Interval_summation(int p, int l, int r) {//路径求和 
	if(t[p].l >= l&&t[p].r <= r) {
		return t[p].sum;
	}
	int mid = (t[p].l + t[p].r)>>1;
	pushdown(p);   int ans = 0;
	if(l <= mid) ans = (ans + Interval_summation(p<<1, l, r) + mod) % mod;
	if(r > mid) ans = (ans + Interval_summation(p<<1|1, l, r) + mod) % mod;
	return ans;
}

void Tree_addition(int x, int y, int val) {//子树加 
	while (top[x] != top[y]) {
		if(deep[top[x]] < deep[top[y]]) swap(x, y);
		Interval_addition(1, idx[top[x]], idx[x], val);
		x = fa[top[x]];
	}
	if(deep[x] < deep[y]) swap(x ,y);
	Interval_addition(1, idx[y], idx[x], val);
}

void Tree_summation(int x, int y) {//子树求和 
	int ans = 0;
	while (top[x] != top[y]) {
		if(deep[top[x]] < deep[top[y]]) swap(x, y);
		ans = (ans + Interval_summation(1, idx[top[x]], idx[x])) % mod;
		x = fa[top[x]];
	}
	if(deep[x] < deep[y]) swap(x, y);
	ans = (ans + Interval_summation(1, idx[y], idx[x])) % mod;
	printf("%d\n", ans);
}

int main() {
	int xi, yi, op;
	int x, y, z;
	n = re(); m = re();
	s = re(); mod = re();
	for(int i = 1; i <= n; i++) 
		b[i] = re();
	for(int i = 1; i < n; i++) {
		xi = re(); yi = re();
		add(xi, yi); add(yi, xi);
	}
	dfs1(s, 0, 1);
	dfs2(s, s);
	build(1, 1, n);
	while (m--) {
			op = re();
		if(op == 1) {
			x = re(); y = re(); z = re();
			Tree_addition(x, y, z);
		}
		else if(op == 2) {
			x = re(); y = re();
			Tree_summation(x, y);
		}
		else if(op == 3) {
			x = re(); z = re();
			Interval_addition(1, idx[x], idx[x] + tot[x] - 1, z % mod);
		}
		else if(op == 4) {
			x = re();
			cout << Interval_summation(1, idx[x], idx[x] + tot[x] - 1) << endl;
		}
	}
	return 0;
}
2021/9/2 08:36
加载中...