Submission #1366042

#TimeUsernameProblemLanguageResultExecution timeMemory
1366042gelastropodJOI Tour 2 (JOI26_joitour)C++20
21 / 100
1120 ms1114112 KiB
#pragma GCC optimize("O3,inline")
#include <bits/stdc++.h>
using namespace std;
#define int long long

vector<int> A, B, kyh, wyk, guys, d, bigW, gcj;
vector<vector<int>> adjlist, p2;
vector<vector<pair<signed, signed>>> jlcx;
deque<int> goon;

int cnt = 0, sqrtN, ysh = -1, N, M, Q;

void dfs(int n, int p) {
    p2[0][n] = p;
    if (p != -1) d[n] = d[p] + 1;
    kyh[n] = cnt++;
    guys.push_back(n);
    for (int i : adjlist[n]) if (i != p) dfs(i, n);
    wyk[n] = cnt++;
    guys.push_back(n);
}

int lca(int a, int b) {
    if (d[a] < d[b]) swap(a, b);
    for (int i = 0; i < 20; i++) if ((d[a] - d[b]) & (1LL << i)) a = p2[i][a];
    if (a == b) return a;
    for (int i = 19; i >= 0; i--) if (p2[i][a] != p2[i][b]) a = p2[i][a], b = p2[i][b];
    return p2[0][a];
}

bool comp(pair<pair<int, int>, int> a, pair<pair<int, int>, int> b) {
    if (a.first.first / sqrtN == b.first.first / sqrtN) return a.first.second < b.first.second;
    return a.first.first < b.first.first;
}

void handle(int a, int b, int c, int _d) {
    if (b) {
        if (c) {
            if (goon.back() == ysh) ysh = -1;
            goon.pop_back();
            if (goon.empty()) return;
            if (ysh == -1 || d[goon.back()] < d[ysh]) ysh = goon.back();
            jlcx[goon.front()].push_back({ a, -_d });
            jlcx[goon.back()].push_back({ a, -_d });
            jlcx[ysh].push_back({ a, _d });
            if (ysh) jlcx[p2[0][ysh]].push_back({ a, _d });
            return;
        }
        if (goon.front() == ysh) ysh = -1;
        goon.pop_front();
        if (goon.empty()) return;
        if (ysh == -1 || d[goon.front()] < d[ysh]) ysh = goon.front();
        jlcx[goon.front()].push_back({ a, -_d });
        jlcx[goon.back()].push_back({ a, -_d });
        jlcx[ysh].push_back({ a, _d });
        if (ysh) jlcx[p2[0][ysh]].push_back({ a, _d });
        return;
    }
    if (goon.size()) {
        jlcx[goon.front()].push_back({ a, _d });
        jlcx[goon.back()].push_back({ a, _d });
        jlcx[ysh].push_back({ a, -_d });
        if (ysh) jlcx[p2[0][ysh]].push_back({ a, -_d });
    }
    if (ysh == -1 || d[a] < d[ysh]) ysh = a;
    if (c) goon.push_back(a);
    else goon.push_front(a);
}

void mk(int n, int p) {
    for (int i = 0; i < Q; i++) if (0 <= B[i] - A[n] && B[i] - A[n] <= N) bigW[i] -= gcj[B[i] - A[n]];
    for (auto i : jlcx[n]) gcj[A[i.first]] += i.second;
    for (int i : adjlist[n]) {
        if (i == p) continue;
        mk(i, n);
    }
    for (int i = 0; i < Q; i++) if (0 <= B[i] - A[n] && B[i] - A[n] <= N) bigW[i] += gcj[B[i] - A[n]];
}

signed main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int a, b; cin >> N;
    sqrtN = sqrt(N);
    adjlist.resize(N, vector<int>());
    kyh.resize(N, -1);
    wyk.resize(N, -1);
    d.resize(N, 0);
    p2.resize(20, vector<int>(N, -1));
    vector<pair<pair<int, int>, int>> quers;
    for (int i = 0; i < N; i++) {
        cin >> a;
        A.push_back(a);
    }
    for (int i = 0; i < N - 1; i++) {
        cin >> a >> b; a--, b--;
        adjlist[a].push_back(b);
        adjlist[b].push_back(a);
    }
    dfs(0, -1);
    for (int i = 1; i < 20; i++) {
        for (int j = 0; j < N; j++) {
            if (p2[i - 1][j] == -1) continue;
            p2[i][j] = p2[i - 1][p2[i - 1][j]];
        }
    }
    cin >> M;
    for (int i = 0; i < M; i++) {
        cin >> a >> b; a--, b--;
        if (kyh[a] > kyh[b]) swap(a, b);
        int clca = lca(a, b);
        if (a == clca) quers.push_back({ { kyh[a], kyh[b] + 1 }, -1 });
        else quers.push_back({ { wyk[a], kyh[b] + 1 }, clca });
    }
    sort(quers.begin(), quers.end(), comp);
    cin >> Q;
    for (int i = 0; i < Q; i++) {
        cin >> a;
        B.push_back(a);
    }
    pair<int, int> crntr = { 0, 0 };
    bitset<100005> visited = 0;
    jlcx.resize(N, vector<pair<signed, signed>>());
    gcj.resize(N + 1, 0);
    for (int i = 0; i < M; i++) {
        while (crntr.second < quers[i].first.second) {
            handle(guys[crntr.second], visited[guys[crntr.second]], 1, M - i);
            visited[guys[crntr.second++]].flip();
        }
        while (crntr.first > quers[i].first.first) {
            visited[guys[--crntr.first]].flip();
            handle(guys[crntr.first], !visited[guys[crntr.first]], 0, M - i);
        }
        while (crntr.second > quers[i].first.second) {
            visited[guys[--crntr.second]].flip();
            handle(guys[crntr.second], !visited[guys[crntr.second]], 1, M - i);
        }
        while (crntr.first < quers[i].first.first) {
            handle(guys[crntr.first], visited[guys[crntr.first]], 0, M - i);
            visited[guys[crntr.first++]].flip();
        }
        if (quers[i].second == -1 || goon.empty()) continue;
        jlcx[goon.front()].push_back({ quers[i].second, 1 });
        jlcx[goon.back()].push_back({ quers[i].second, 1 });
        jlcx[ysh].push_back({ quers[i].second, -1 });
        if (ysh) jlcx[p2[0][ysh]].push_back({ quers[i].second, -1 });
    }
    bigW.resize(Q, 0);
    mk(0, -1);
    for (int i : bigW) cout << i << '\n';
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...