Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

Eau de Cologne

[Working In Progress] Euler Tour Trick + LCA + HLD Template 본문

rkgk

[Working In Progress] Euler Tour Trick + LCA + HLD Template

cologne 2023. 5. 5. 19:41
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
struct EulerTour
{
    int N;
    vector<int> SZ, H;
    vector<pair<intint>> ETT;
    vector<vector<int>> childs, sp;
    vector<vector<pair<intint>>> rngs;
    EulerTour(){};
    EulerTour(vector<vector<int>> G, int root = 0)
        : N(G.size()), SZ(N), H(N), ETT(N), childs(N),
          sp(bit_width((unsigned)N), vector<int>(N)), rngs(N)
    {
        function<void(intintint)> dfs = [&](int a, int p, int h)
        {
            sp[0][a] = p, SZ[a] = 1, H[a] = h;
            for (auto &b : G[a])
                if (b != p)
                {
                    dfs(b, a, h + 1);
                    SZ[a] += SZ[b];
                    if (G[a][0== p || SZ[G[a][0]] < SZ[b])
                        swap(b, G[a][0]);
                }
        };
        dfs(root, -10);
        for (int i = 1; i < (int)sp.size(); ++i)
            for (int j = 0; j < N; ++j)
                if (sp[i - 1][j] != -1)
                    sp[i][j] = sp[i - 1][sp[i - 1][j]];
 
        int gidx = 0;
        vector<pair<intint>> rng;
        function<void(int)> ett = [&](int a)
        {
            if (rng.empty() || rng.back().second != gidx)
                rng.emplace_back(gidx, gidx + 1);
            else
                rng.back().second++;
 
            ETT[a].first = gidx++;
            rngs[a] = rng;
            for (int b : G[a])
                if (b != sp[0][a])
                    ett(b);
            ETT[a].second = gidx;
 
            if (rng.back().first + 1 == rng.back().second)
                rng.pop_back();
            else
                rng.back().second--;
        };
        ett(root);
    }
 
    int lca(int u, int v)
    {
        if (H[u] < H[v])
            swap(u, v);
        int hdiff = H[u] - H[v];
        for (int i = 0; i < (int)sp.size(); ++i)
            if (hdiff & (1 << i))
                u = sp[i][u];
        if (u == v)
            return u;
        for (int i = (int)sp.size() - 1; i >= 0--i)
        {
            int pu = sp[i][u], pv = sp[i][v];
            if (pu != pv)
                u = pu, v = pv;
        }
        return sp[0][u];
    }
 
    pair<intint> subtree(int a) { return ETT[a]; }
    vector<pair<intint>> rootpath(int a) { return rngs[a]; }
    vector<pair<intint>> path(int u, int v)
    {
        int r = ETT[lca(u, v)].first;
        vector<pair<intint>> ret;
        for (auto [s, e] : rootpath(u))
            if (e + 1 >= r)
                ret.emplace_back(max(s, r), e);
        for (auto [s, e] : rootpath(v))
            if (e >= r)
                ret.emplace_back(max(s, r + 1), e);
        return ret;
    }
};
cs

Sample Usage:

'rkgk' 카테고리의 다른 글

졸업하고싶다  (0) 2023.07.19
FastIO 메모  (0) 2023.05.25
가성비 에라토스테네스의 체  (0) 2023.04.27
Karp의 최소 사이클 평균 가중치 알고리즘  (1) 2022.09.23
[JOISC 2022] Broken Device 2  (0) 2022.09.22