求助蒟蒻刚学树剖
  • 板块题目总版
  • 楼主fussyguy
  • 当前回复4
  • 已保存回复4
  • 发布时间2021/3/31 13:52
  • 上次更新2023/11/5 01:20:11
查看原帖
求助蒟蒻刚学树剖
362112
fussyguy楼主2021/3/31 13:52
#include <cstdio>
#include <iostream>
#define gc getchar()
#define W while
#define FOR(i, x, y) for (register int i = x; i <= y; ++i)
#define ROF(i, x, y) for (register int i = x; i >= y; --i)
using namespace std;

const int N = 1e5 + 5;
const int M = 2e5 + 5;

int n;

int cnt;
int a[N];
int head[N];
struct edge {
	int u;
    int v;
    int w;
    int nxt;
} e[M];

struct segtree {
    int l;
    int r;
    int mxn;
    int sum;
    int lazy;
} t[M << 2]; 

int o;
int fa[M];
int son[M];
int dep[M];
int siz[M];
int dfn[M];
int rnk[M];
int top[M];

inline void ins(int u, int v, int w) {
    e[++cnt] = { u, v, w, head[u] };
    head[u] = cnt;
}

void dfs1(int x, int f, int depth) {
    fa[x] = f;
    siz[x] = 1;
    dep[x] = depth;
    int maxson = -1;
    for (int i = head[x]; i; i = e[i].nxt) {
        int y = e[i].v;
        if (y == f) continue;
		a[y] = e[i].w;
        dfs1(y, x, depth + 1);        
        siz[x] += siz[y];
        if (siz[y] > maxson) {
            maxson = siz[y];
            son[x] = y;
        }
    }
}
void dfs2(int x, int t) {
    top[x] = t;
    o++;
    rnk[o] = a[x];
    dfn[x] = o;
    if (!son[x]) return;
    dfs2(son[x], t);
    for (int i = head[x]; i; i = e[i].nxt) {
        int y = e[i].v;
        if (y == fa[x] or y == son[x]) continue;
        dfs2(y, y);
    }
}

inline int len(int p) { return t[p].r - t[p].l + 1; }
inline void update(int p) {
    t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
    t[p].mxn = max(t[p << 1].mxn, t[p << 1 | 1].mxn);
}
inline void brush(int p, int k) {
    t[p].lazy += k;
    t[p].mxn += k;
    t[p].sum += len(p) * k;
}
inline void push_down(int p) {
    brush(p << 1, t[p].lazy);
    brush(p << 1 | 1, t[p].lazy);
    t[p].lazy = 0;
}

void build(int p, int l, int r) {
    t[p].l = l;
    t[p].r = r;
    if (l == r) {
        t[p].sum = rnk[l];
        t[p].mxn = rnk[l];
        return;
    }
    int mid = l + r >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    update(p);
}

void change(int p, int i, int k) {
    if (t[p].l == t[p].r and t[p].l == i) {
        t[p].sum = k;
        t[p].mxn = k;
        t[p].lazy = 0;
        return;
    }
    int mid = t[p].l + t[p].r >> 1;
    push_down(p);
    if (i <= mid) change(p << 1, i, k);
    else change(p << 1 | 1, i, k);
    update(p);
}

void add(int p, int l, int r, int k) {
    if (t[p].l >= l and t[p].r <= r) {
        brush(p, k);
        return;
    }
    int mid = t[p].l + t[p].r >> 1;
    push_down(p);
    if (l <= mid) add(p << 1, l, r, k);
    if (r >= mid + 1) add(p << 1 | 1, l, r, k);
    update(p);
}
void range_add(int x, int y, int k) {
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        add(1, dfn[top[x]], dfn[x], k);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    if (dep[x] != dep[y]) {
        add(1, dfn[x] + 1, dfn[y], k);
    }
}

int getmax(int p, int l, int r) {
	if (t[p].l >= l and t[p].r <= r) {
		return t[p].mxn;
	}
	int mid = t[p].l + t[p].r >> 1;
	push_down(p);
	int MXN = -9999999999;
	if (l <= mid) MXN = max(MXN, getmax(p << 1, l, r));
	if (r > mid) MXN = max(MXN, getmax(p << 1 | 1, l, r));
	return MXN;
}
int range_getmax(int x, int y) {
	int MXN = -9999999999;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		MXN = max(MXN, getmax(1, dfn[top[x]], dfn[x]));
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	if (dep[x] != dep[y]) {
		MXN = max(MXN, getmax(1, dfn[x] + 1, dfn[y]));
	} 
	return MXN;
}

void cover(int p, int l, int r, int k) {
	if (t[p].l >= l and t[p].r <= r) {
		t[p].sum = k;
		t[p].mxn = k;
		t[p].lazy = 0;
		return;
	}
	int mid = t[p].l + t[p].r >> 1;
	push_down(p);
	if (l <= mid)
		cover(p << 1, l, r, k);
	if (r >= mid + 1)
		cover(p << 1 | 1, l, r, k);
	update(p);
	return;
}
void range_cover(int x, int y, int k) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		cover(1, dfn[top[x]], dfn[x], k);
		x = fa[top[x]];
	}	
	if (dep[x] > dep[y]) swap(x, y);
	if (dep[x] != dep[y]) {
		cover(1, dfn[x] + 1, dfn[y], k);
	}
	return;
}

int main() {
cin .tie(NULL);
cout.tie(NULL);
ios::sync_with_stdio(false);
//=======================================================
    cin >> n;
    FOR(i, 1, n - 1) {
        int u, v, w;
        cin >> u >> v >> w;
        ins(u, v, w);
        ins(v, u, w);
    }

    dfs1(1, 0, 1);
    dfs2(1, 1);
    build(1, 1, n);

    string op;
    cin >> op;
    while (op != "Stop") {
        if (op == "Max") {
        	int l, r;
        	cin >> l >> r;
        	cout << range_getmax(l, r) << endl;
		}
		if (op == "Cover") {
			int l, r, k;
			cin >> l >> r >> k;
			range_cover(l, r, k);
		}
		if (op == "Add") {
			int l, r, k;
			cin >> l >> r >> k;
			range_add(l, r, k);
		}
		if (op == "Change") {
			int i, w;
			cin >> i >> w;
			i *= 2;
			if (dep[e[i].v] > dep[e[i].u]) {
				change(1, dfn[e[i].v], w);
			}			
			else change(1, dfn[e[i].u], w);
		}
        cin >> op;
    }
//=======================================================
return 0;
}
2021/3/31 13:52
加载中...