Submission #1285397

#TimeUsernameProblemLanguageResultExecution timeMemory
1285397chikien2009Synchronization (JOI13_synchronization)C++20
100 / 100
882 ms32992 KiB
#include <bits/stdc++.h>

using namespace std;

void setup()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

struct SEGMENT_TREE
{
    int tree[400000];
    inline void Set(int ind, int l, int r, int x, int v)
    {
        if (r < x || x < l)
        {
            return;
        }
        if (l == r)
        {
            tree[ind] = v;
            return;
        }
        int m = (l + r) >> 1;
        Set(ind << 1, l, m, x, v);
        Set(ind << 1 | 1, m + 1, r, x, v);
        tree[ind] = tree[ind << 1] + tree[ind << 1 | 1];
    }
    inline int Get(int ind, int l, int r, int x, int y)
    {
        if (r < x || y < l)
        {
            return 0;
        }
        if (x <= l && r <= y)
        {
            return tree[ind];
        }
        int m = (l + r) >> 1;
        return Get(ind << 1, l, m, x, y) + Get(ind << 1 | 1, m + 1, r, x, y);
    }
} st;

int n, m, q, a, b, c;
int depth[100000], sz[100000], head[100000], id[100000], ind[100000], pre[100000];
int last[100000], v[100000];
bool on[100000];
pair<int, int> e[100000];
vector<pair<int, int>> g[100000];

inline void DFS(int node, int par)
{
    sz[node] = 1;
    pre[node] = par;
    for (auto &i : g[node])
    {
        if (i.first != par)
        {
            depth[i.first] = depth[node] + 1;
            DFS(i.first, node);
            sz[node] += sz[i.first];
            if (e[i.second].first == i.first)
            {
                swap(e[i.second].first, e[i.second].second);
            }
        }
    }
}

inline void HLD(int node, int par)
{
    int mx = 0;
    id[node] = a++;
    ind[id[node]] = node;
    for (auto &i : g[node])
    {
        if (i.first != par)
        {
            mx = max(mx, sz[i.first]);
        }
    }
    for (auto &i : g[node])
    {
        if (i.first != par && sz[i.first] == mx)
        {
            head[i.first] = head[node];
            HLD(i.first, node);
            break;
        }
    }
    for (auto & i : g[node])
    {
        if (i.first != par)
        {
            if (sz[i.first] == mx)
            {
                mx = -1;
                continue;
            }
            else
            {
                head[i.first] = i.first;
                HLD(i.first, node);
            }
        }
    }
}

inline int GoUp(int node)
{
    if (st.Get(1, 0, n - 1, id[head[node]], id[node]) == depth[node] - depth[head[node]] + 1)
    {
        return GoUp(pre[head[node]]);
    }
    for (int i = 19, j; i >= 0; --i)
    {
        j = id[node] - (1 << i);
        if (id[head[node]] <= j && st.Get(1, 0, n - 1, j + 1, id[node]) == depth[node] - depth[ind[j]])
        {
            node = ind[j];
        }
    }
    return node;
}

int main()
{
    setup();

    cin >> n >> m >> q;
    for (int i = 0; i < n - 1; ++i)
    {
        cin >> e[i].first >> e[i].second;
        g[--e[i].first].push_back({--e[i].second, i});
        g[e[i].second].push_back({e[i].first, i});
    }
    fill_n(v, n, 1);
    a = 0;
    DFS(0, 0);
    HLD(0, 0);
    while (m--)
    {
        cin >> a;
        a--;
        if (on[a])
        {
            b = GoUp(e[a].second);
            v[e[a].second] = last[a] = v[b];
            st.Set(1, 0, n - 1, id[e[a].second], 0);
        }
        else
        {
            b = GoUp(e[a].first);
            v[b] += v[e[a].second] - last[a];
            st.Set(1, 0, n - 1, id[e[a].second], 1);
        }
        on[a] ^= 1;
    }
    while (q--)
    {
        cin >> a;
        cout << v[GoUp(a - 1)] << "\n";
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...