求会树链剖分+线段树的大佬调
  • 板块学术版
  • 楼主_Accepted_100
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/8/14 12:01
  • 上次更新2024/8/14 14:24:50
查看原帖
求会树链剖分+线段树的大佬调
1039923
_Accepted_100楼主2024/8/14 12:01

题目: [SDOI2014] 旅行

#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const int INF = 0x7fffffff;
const int N = 100010;
int id[N], root[N];
int cnt;

struct Treenode {
	int l, r;
	int lc, rc;
	int maxn, sum;
} t[N << 8];

inline int newnode(int l, int r) {
	int p = ++cnt;
	t[p].l = l;
	t[p].r = r;
	return p;
}

inline void maintain(int p) {
	t[p].sum = t[t[p].lc].sum + t[t[p].rc].sum;
	t[p].maxn = max (t[t[p].lc].maxn, t[t[p].rc].maxn);
}

void build(int p, int k, int val) {
	if (t[p].l == t[p].r) {
		t[p].sum = t[p].maxn = val;
		return;
	}
	int mid = (t[p].l + t[p].r) >> 1;
	if (k <= mid) {
		if (!t[p].lc) t[p].lc = newnode(t[p].l, mid);
		build(t[p].lc, k, val);
	} else {
		if (!t[p].rc) t[p].rc = newnode(mid + 1, t[p].r);
		build(t[p].rc, k, val);
	}
	maintain(p);
}

void update(int p, int x, int k) {
	if (t[p].l == t[p].r) {
		t[p].sum = t[p].maxn = k;
		return;
	}
	int mid = (t[p].l + t[p].r) >> 1;
	if (x <= mid) update(t[p].lc, x, k);
	else update(t[p].rc, x, k);
	maintain(p);
}

int query_sum(int p, int l, int r) {
	if (p == 0) return 0;
	if (l <= t[p].l and t[p].r <= r) return t[p].sum;
	int mid = (t[p].l + t[p].r) >> 1, res = 0;
	if (l <= mid) res += query_sum(t[p].lc, l, r);
	if (r > mid) res += query_sum(t[p].rc, l, r);
	return res;
}

int query_max(int p, int l, int r) {
	if (p == 0) return 0;
	if (l <= t[p].l and t[p].r <= r) return t[p].maxn;
	int mid = (t[p].l + t[p].r) >> 1, res = -INF;
	if (l <= mid) res = max (res, query_max(t[p].lc, l, r));
	if (r > mid) res = max (res, query_max(t[p].rc, l, r));
	return res;
}

int w[N], c[N], fa[N], dep[N], son[N], top[N], size[N];
vector <int> g[N];
int n, q, tot;

void dfs1(int x, int father) {
	fa[x] = father;
	dep[x] = dep[father] + 1;
	size[x] = 1;
	int maxn = 0;
	for (int i = 0; i < g[x].size(); i++) {
		int v = g[x][i];
		if (v == father) continue;
		dfs1(v, x);
		size[x] += size[v];
		if (size[v] > maxn) {
			maxn = size[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topnode) {
	top[x] = topnode;
	id[x] = ++tot;
	build(root[c[x]], id[x], w[x]);
	if (son[x] == 0) return;
	dfs2(son[x], topnode);
	for (int i = 0; i < g[x].size(); i++) {
		int v = g[x][i];
		if (v == son[x] or v == fa[x]) continue;
		dfs2(v, v);
	}
}

void query_sum_path(int x, int y) {
	int ans = 0;
	int b = c[x];
	while(top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		ans += query_sum(root[c[x]], id[top[x]], id[x]);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	cout << ans + query_sum(root[c[x]], id[x], id[y]) << endl; 
}

void query_max_path(int x, int y) {
	int ans = 0;
	int b = c[x];
	while(top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		ans = max (ans, query_max(root[c[x]], id[top[x]], id[x]));
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	cout << max (ans, query_max(root[c[x]], id[x], id[y])) << endl; 
}

int main() {
	ios :: sync_with_stdio(false);
	cin.tie(0); 
	cout.tie(0);
	cin >> n >> q;  
	for (int i = 1; i <= N - 10; i++) root[i] = newnode(1, n);
	for (int i = 1; i <= n; i++) cin >> w[i] >> c[i];
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		g[x].pb(y);
		g[y].pb(x);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	while (q--) {
		string st;
		int x, y;
		cin >> st >> x >> y;
		if (st == "CC") build(root[c[x]], id[x], 0), c[x] = y, build(root[y], id[x], w[x]);
		if (st == "CW") w[x] = y, update(root[c[x]], id[x], y);
		if (st == "QS") query_sum_path(x, y);
		if (st == "QM") query_max_path(x, y);
	}
	return 0;
}
2024/8/14 12:01
加载中...