zoukankan      html  css  js  c++  java
  • 动态开点权值线段树 线段树合并

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef pair<int, pii> pipii;
    
    ll LINF = 0x3F3F3F3F3F3F3F3FLL;
    
    vector<int> G[100005];
    int dep[100005];
    int pa[100005][20];
    
    void dfs1(int u, int p) {
        pa[u][0] = p;
        dep[u] = dep[p] + 1;
        for(int i = 1; i < 20; ++i)
            pa[u][i] = pa[pa[u][i - 1]][i - 1];
        for(int &v : G[u]) {
            if(v == p)
                continue;
            dfs1(v, u);
        }
        return;
    }
    
    int lca(int x, int y) {
        if(dep[x] < dep[y])
            swap(x, y);
        for(int i = 19; i >= 0; --i) {
            if(dep[pa[x][i]] >= dep[y])
                x = pa[x][i];
        }
        if(x == y)
            return x;
        for(int i = 19; i >= 0; --i) {
            if(pa[x][i] != pa[y][i]) {
                x = pa[x][i];
                y = pa[y][i];
            }
        }
        return pa[x][0];
    }
    
    int rt[100005];
    int ls[100005 * 20];
    int rs[100005 * 20];
    int ct[100005 * 20];
    int id[100005 * 20];
    int top;
    
    void Init() {
        top = 0;
        return;
    }
    
    int NewNode() {
        ++top;
        ls[top] = 0;
        rs[top] = 0;
        ct[top] = 0;
        id[top] = 0;
        return top;
    }
    
    void PushUp(int o) {
        if(ct[ls[o]] >= ct[rs[o]]) {
            ct[o] = ct[ls[o]];
            id[o] = id[ls[o]];
        } else {
            ct[o] = ct[rs[o]];
            id[o] = id[rs[o]];
        }
        if(ct[o] == 0)
            id[o] = 0;
        return;
    }
    
    void Add(int o, int l, int r, int p, int v) {
        if(l == r) {
            ct[o] += v;
            id[o] = l;
            return;
        }
        int m = (l + r) >> 1;
        if(p <= m) {
            if(ls[o] == 0)
                ls[o] = NewNode();
            Add(ls[o], l, m, p, v);
        }
        if(p >= m + 1) {
            if(rs[o] == 0)
                rs[o] = NewNode();
            Add(rs[o], m + 1, r, p, v);
        }
        PushUp(o);
        return;
    }
    
    void Merge(int u, int v, int l, int r) {
        if(l == r) {
            ct[u] += ct[v];
            id[u] = l;
            return;
        }
        int m = (l + r) >> 1;
        if(ls[v] != 0) {
            if(ls[u] == 0)
                ls[u] = ls[v];
            else
                Merge(ls[u], ls[v], l, m);
        }
        if(rs[v] != 0) {
            if(rs[u] == 0)
                rs[u] = rs[v];
            else
                Merge(rs[u], rs[v], m + 1, r);
        }
        PushUp(u);
        return;
    }
    
    int x[100005];
    int y[100005];
    int z[100005];
    
    int Z[100005], Ztop;
    vector<int> tag[100005];
    
    void AddTag(int x, int y, int z) {
        tag[x].push_back(z);
        tag[y].push_back(z);
        int l = lca(x, y);
        tag[l].push_back(-z);
        if(pa[l][0] != 0)
            tag[pa[l][0]].push_back(-z);
        return;
    }
    
    int ans[100005];
    
    void dfs2(int u, int p) {
        int maxct = 0, maxctid = 0;
        for(int &v : G[u]) {
            if(v == p)
                continue;
            dfs2(v, u);
            if(ct[rt[v]] > maxct) {
                maxct = ct[rt[v]];
                maxctid = v;
            }
        }
        rt[u] = (maxctid != 0) ? rt[maxctid] : NewNode();
        for(int &v : G[u]) {
            if(v == p || v == maxctid)
                continue;
            Merge(rt[u], rt[v], 1, Ztop);
        }
        for(int &z : tag[u]) {
            int p = z, v = 1;
            if(z < 0)
                p = -z, v = -1;
            Add(rt[u], 1, Ztop, p, v);
        }
        ans[u] = Z[id[rt[u]]];
        return;
    }
    
    void solve() {
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) {
            G[i].clear();
            tag[i].clear();
        }
        for(int i = 1; i <= n - 1; ++i) {
            int a, b;
            scanf("%d%d", &a, &b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        dfs1(1, 0);
        Ztop = 0;
        for(int i = 1; i <= m; ++i) {
            scanf("%d%d%d", &x[i], &y[i], &z[i]);
            Z[++Ztop] = z[i];
        }
        sort(Z + 1, Z + 1 + Ztop);
        Ztop = unique(Z + 1, Z + 1 + Ztop) - (Z + 1);
        for(int i = 1; i <= m; ++i) {
            z[i] = lower_bound(Z + 1, Z + 1 + Ztop, z[i]) - Z;
            AddTag(x[i], y[i], z[i]);
        }
        dfs2(1, 0);
        for(int i = 1; i <= n; ++i)
            printf("%d
    ", ans[i]);
        return;
    }
    
    int main() {
    #ifdef LOCAL
        freopen("lyz.txt", "r", stdin);
    #endif // LOCAL
        solve();
        return 0;
    }
    
  • 相关阅读:
    多通道 移位寄存器 verilog
    modelsim-altera IP核仿真
    modelsim-altera
    YUV视频显示软件+源码
    opencl教程
    使用VisualStudio读写NI FPGA板卡实例(基于FPGA Interface C API Generator)
    Visual Studio编译与调用DLL方法
    NI FPGA板卡程序设计概述
    LabVIEW中使用GPU进行高性能计算
    Windows平台编程涉及的函数
  • 原文地址:https://www.cnblogs.com/purinliang/p/13884778.html
Copyright © 2011-2022 走看看