线段树合并模板求调
查看原帖
线段树合并模板求调
297778
badFlamesへ楼主2022/8/12 15:51

蒟蒻刚学指针,写的不熟练

这是20pts的代码,基本都 WAWA

QAQ

#include <bits/stdc++.h> // unfinished P4556
#define mid (l + r >> 1)
#define mxz 100001
using namespace std;
const int N = 3e5 + 5;

inline int read() {
    int x = 0, w = 0, ch = getchar();
    for(; !isdigit(ch); ch = getchar()) w |= ch == 45;
    for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
    return w ? -x : x;
}

int n, m;
vector <int> Link[N];

struct Node {
    Node *l, *r;
    int mx, mxp;
}*nil;

inline void init(Node *&p) {
    p->l = p->r = nil;
    p->mx = 0, p->mxp = 1e9;
}

inline void pushup(Node *p) {
    if(p->l->mx > p->r->mx) p->mx = p->l->mx, p->mxp = p->l->mxp;
    else if(p->l->mx < p->r->mx) p->mx = p->r->mx, p->mxp = p->r->mxp;
    else p->mx = p->l->mx, p->mxp = min(p->l->mxp, p->r->mxp);
}

void update_(Node *&p, int l, int r, int x, int v) {
    if(p == nil) init(p = new Node());
    if(l == r) { p->mx += v, p->mxp = x; return; }
    x <= mid ? update_(p->l, l, mid, x, v) : update_(p->r, mid + 1, r, x, v);
    pushup(p);
}

Node *Mg(Node *x, Node *y, int l, int r) {
    if(x == nil) return y; if(y == nil) return x;
    if(l == r) { x->mx += y->mx; return x; }
    x->l = Mg(x->l, y->l, l, mid); x->r = Mg(x->r, y->r, mid + 1, r);
    pushup(x); return x;
}

struct Sgtree {
    Node *rt;
    const inline void update(int x, int v) { update_(rt, 1, mxz, x, v); }
    const inline void Merge(Sgtree that) { Mg(rt, that.rt, 1, mxz); }
    const inline void initiate() { rt = nil; }
    const inline int queryall() { return rt->mxp; }
}s[N];

namespace LCA_ {
    int dep[N], fa[N], sz[N], son[N], top[N];
    void dfs1(int u, int F) {
        dep[u] = dep[F] + 1, fa[u] = F, sz[u] = 1;
        for(auto v : Link[u]) {
            if(v == F) continue;
            dfs1(v, u);
            sz[u] += sz[v];
            if(sz[son[u]] < sz[v]) son[u] = v;
        }
    }
    void dfs2(int u, int tp) {
        top[u] = tp;
        if(!son[u]) return; dfs2(son[u], tp);
        for(auto v : Link[u]) if(v != fa[u] && v != son[u]) dfs2(v, v);
    }
    inline int Lca(int x, int y) {
        while(top[x] != top[y]) {
            if(dep[top[x]] <= dep[top[y]]) swap(x, y);
            x = fa[top[x]];
        }
        return dep[x] < dep[y] ? x : y;
    }
}using namespace LCA_;

int ret[N];

void Calc(int u) {
    for(auto v : Link[u]) 
        if(v != fa[u]) Calc(v), s[u].Merge(s[v]);
    ret[u] = s[u].queryall();
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("Ans.txt", "w", stdout);
#endif
    //init(nil = new Node());
    nil = new Node();
    nil->l = nil->r = nil;
    //init(nil);
    n = read(), m = read();
    for(int i = 1; i < n; ++i) {
        register int x = read(), y = read();
        Link[x].push_back(y);
        Link[y].push_back(x);
    }
    //Link[0].push_back(1);
    dfs1(1, 0);
    dfs2(1, 1);
    for(int i = 0; i <= n; ++i) s[i].initiate();

    for(int i = 1; i <= m; ++i) {
        register int x = read(), y = read(), z = read();
        register int t = Lca(x, y);
        //cout << "-> " << t << endl;
        s[x].update(z, 1); s[y].update(z, 1);
        s[t].update(z, -1); 
        if(fa[t]) s[fa[t]].update(z, -1);
    }
    //return 0;
    Calc(1);
    for(int i = 1; i <= n; ++i) printf("%d\n", ret[i]);
    return 0;
}

2022/8/12 15:51
加载中...