제출 #1348417

#제출 시각아이디문제언어결과실행 시간메모리
1348417MisterReaperTourism (JOI23_tourism)C++20
100 / 100
643 ms22796 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

struct fenwick {
    int n;
    std::vector<int> tree;
    fenwick(int n_) : n(n_), tree(n + 1) {}
    void modify(int p, int x) {
        for (p += 1; p <= n; p += p & -p) {
            tree[p] += x;
        }
    }
    int get(int p) {
        int res = 0;
        for (p += 1; p; p -= p & -p) {
            res += tree[p];
        }
        return res;
    }
    int get(int l, int r) {
        return get(r) - get(l - 1);
    }
};

constexpr int max_N = int(1E5) + 5;

int N;
int M;
int Q;
std::vector<int> adj[max_N];
int C[max_N];
int L[max_N];
int R[max_N];
int tim = 0;
int par[max_N];
int top[max_N];
int siz[max_N];
int tin[max_N];
int tout[max_N];
int dep[max_N];
std::vector<int> ask[max_N];
int ans[max_N];

void dfs1(int v) {
    siz[v] = 1;
    for (auto& u : adj[v]) {
        adj[u].erase(std::find(adj[u].begin(), adj[u].end(), v));
        dep[u] = dep[v] + 1;
        par[u] = v;
        dfs1(u);
        siz[v] += siz[u];
        if (siz[u] > siz[adj[v][0]]) {
            std::swap(u, adj[v][0]);
        }
    }
}

void dfs2(int v) {
    tin[v] = tim++;
    for (auto u : adj[v]) {
        if (u == adj[v][0]) {
            top[u] = top[v];
        } else {
            top[u] = u;
        }
        dfs2(u);
    }
    tout[v] = tim;
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::cin >> N >> M >> Q;

    for (int i = 1; i < N; ++i) {
        int A, B;
        std::cin >> A >> B;
        --A, --B;
        adj[A].emplace_back(B);
        adj[B].emplace_back(A);
    }

    for (int i = 0; i < M; ++i) {
        std::cin >> C[i];
        --C[i];
    }

    for (int i = 0; i < Q; ++i) {
        std::cin >> L[i] >> R[i];
        --L[i];
        ask[L[i]].emplace_back(i);
    }

    dfs1(0);
    dfs2(0);

    fenwick fen(M + 1);
    std::map<int, int> mp;
    mp[0] = M;
    fen.modify(M, N);

    for (int i = M - 2; i >= 0; --i) {
        int u = C[i];
        int v = C[i + 1];
        std::vector<std::pair<int, int>> rngs;
        while (top[u] != top[v]) {
            if (dep[top[u]] < dep[top[v]]) {
                std::swap(u, v);
            }
            rngs.emplace_back(tin[top[u]], tin[u] + 1);
            u = par[top[u]];
        }
        if (dep[u] < dep[v]) {
            std::swap(u, v);
        }
        if (u != v) {
            rngs.emplace_back(tin[v] + 1, tin[u] + 1);
        }
        debug(rngs);
        for (auto[l, r] : rngs) { // [l, r)
            for (auto j : {l, r}) {
                if (!mp.contains(j)) {
                    mp[j] = std::prev(mp.lower_bound(j))->second;
                }
            }
            auto it = mp.lower_bound(l);
            while (it->first != r) {
                fen.modify(it->second, -(std::next(it)->first - it->first));
                it = mp.erase(it);
            }
            mp[l] = i + 1;
            fen.modify(i + 1, r - l);
        }
        for (auto q : ask[i]) {
            ans[q] = fen.get(R[q] - 1);
        }
    }

    for (int i = 0; i < Q; ++i) {
        std::cout << ans[i] + 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...
#Verdict Execution timeMemoryGrader output
Fetching results...