• luoguP3359 改造异或树 线段树合并


    删边转化为加边

    然后每次用线段树合并就行.....

    确确实实很简单

    然而为什么线段树合并跑不过$splay$的启发式合并,常数稍大了点...

    复杂度$O(n log n)$

    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    namespace remoon {
        #define ri register int
        #define ll long long
        #define tpr template <typename ra>
        #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
        #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)    
        #define gc getchar
        inline int read() {
            int p = 0, w = 1; char c = gc();
            while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
            while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
            return p * w;
        }
        int wr[50], rw;
        #define pc(iw) putchar(iw)
        tpr inline void write(ra o, char c = '
    ') {
            if(!o) pc('0');
            if(o < 0) o = -o, pc('-');
            while(o) wr[++ rw] = o % 10, o /= 10;
            while(rw) pc(wr[rw --] + '0');
            pc(c);
        }
    }
    using namespace std;
    using namespace remoon;

    #define sid 200050 #define pid 5000500 ll ans; ll sum[sid]; int n, id, cnp; int x[sid], y[sid], p[sid]; int cap[sid], nxt[sid], node[sid], val[sid], s[sid]; int fa[sid], rt[sid], ls[pid], rs[pid], sz[pid]; inline void addedge(int u, int v, int w) { nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v; val[cnp] = w; nxt[++ cnp] = cap[v]; cap[v] = cnp; node[cnp] = u; val[cnp] = w; } inline int find(int o) { if(fa[o] == o) return o; return fa[o] = find(fa[o]); } inline void insert(int &now, int l, int r, int v) { now = ++ id; sz[now] = 1; if(l == r) return; int mid = (l + r) >> 1; if(v <= mid) insert(ls[now], l, mid, v); else insert(rs[now], mid + 1, r, v); } inline int merge(int x, int y, int l = 0, int r = 1 << 30) { if(!x || !y) return x + y; if(l == r) ans += 1ll * sz[x] * sz[y]; int mid = (l + r) >> 1; ls[x] = merge(ls[x], ls[y], l, mid); rs[x] = merge(rs[x], rs[y], mid + 1, r); sz[x] += sz[y]; return x; } #define cur node[i] inline void dfs(int o, int f) { insert(rt[o], 0, 1 << 30, s[o]); for(int i = cap[o]; i; i = nxt[i]) if(cur != f) s[cur] = s[o] ^ val[i], dfs(cur, o); } int main() { n = read(); rep(i, 1, n - 1) { x[i] = read(); y[i] = read(); int w = read(); addedge(x[i], y[i], w); } rep(i, 1, n) fa[i] = i; rep(i, 1, n - 1) p[i] = read(); dfs(1, 0); drep(i, n - 1, 1) { int u = find(x[p[i]]), v = find(y[p[i]]); fa[v] = u; merge(rt[u], rt[v]); sum[i] = ans; } rep(i, 1, n) write(sum[i]); return 0; }
  • 相关阅读:
    kubernetes 节点数据彻底清理脚本
    多es 集群数据迁移方案
    .Net Framework各版本微软技术支持及到期日期
    etcd raft 处理流程图系列3-wal的读写
    etcd raft 处理流程图系列2-transport
    etcd raft 处理流程图系列1-raftexample
    一种分布式预写日志系统
    自适应软件缓存管理
    require/import路径中的叹号是什么?
    理解原型链
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9846715.html
Copyright © 2020-2023  润新知