Submission #1060447

#TimeUsernameProblemLanguageResultExecution timeMemory
1060447_callmelucianTourism (JOI23_tourism)C++14
100 / 100
173 ms41552 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pl;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tt;

#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())

const int mn = 1e5 + 5;
int up[mn][18], spt[mn][18], depth[mn], ans[mn], chain[mn], sz[mn];
vector<pii> qry[mn], block[mn];
vector<int> adj[mn];

struct BIT {
    vector<int> tr;
    BIT (int sz) : tr(sz + 1) {}

    int p (int k) { return k & -k; };

    void update (int k, int val) {
        for (; k < tr.size(); k += p(k)) tr[k] += val;
    }

    int preSum (int k, int ans = 0) {
        for (; k > 0; k -= p(k)) ans += tr[k];
        return ans;
    }

    int query (int l, int r) {
        return preSum(r) - preSum(l - 1);
    }
} freqTable(mn);

void preDfs (int u, int p, int d) {
    depth[u] = d, up[u][0] = p, sz[u] = 1;
    for (int i = 1; i < 18; i++)
        up[u][i] = up[up[u][i - 1]][i - 1];
    for (int v : adj[u]) {
        if (v == p) continue;
        preDfs(v, u, d + 1);
        sz[u] += sz[v];
    }
}

void dfs (int u, int p, bool toParent) {
    if (toParent) chain[u] = chain[p];
    else chain[u] = u;

    function<bool(int,int)> cmp = [&] (int a, int b) {
        return sz[a] > sz[b];
    };
    bool heavy = 1;
    for (int v : adj[u])
        if (v != p) dfs(v, u, heavy), heavy = 0;
}

int goUp (int u, int k) {
    for (int i = 0; i < 18; i++)
        if (k & (1 << i)) u = up[u][i];
    return u;
}

int lca (int a, int b) {
    if (depth[a] < depth[b]) swap(a, b);
    a = goUp(a, depth[a] - depth[b]);
    if (a == b) return a;
    for (int i = 17; i >= 0; i--)
        if (up[a][i] != up[b][i]) a = up[a][i], b = up[b][i];
    return up[a][0];
}

int queryLCA (int l, int r) {
    int p = 31 - __builtin_clz(r - l + 1);
    return lca(spt[l][p], spt[r - (1 << p) + 1][p]);
}

void change (int gr, int prf, int val) {
    int prv = 0;
    while (block[gr].size() && block[gr].back().first <= prf) {
        int pos, curv; tie(pos, curv) = block[gr].back();
        block[gr].pop_back();
        freqTable.update(curv, -(pos - prv));
        prv = pos;
    }
    if (block[gr].size())
        freqTable.update(block[gr].back().second, -(prf - prv));
    block[gr].push_back({prf, val});
    freqTable.update(val, prf);
}

void update (int u, int val) {
    while (u) {
        change(chain[u], depth[u] - depth[chain[u]] + 1, val);
        u = up[chain[u]][0];
    }
}

/*
    For each query, count the number of nodes that is
    the parent of at least one of the queried nodes,
    minus the depth of the queried nodes' LCA.
*/

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, m, q; cin >> n >> m >> q;
    for (int i = 1; i < n; i++) {
        int a, b; cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    preDfs(1, 0, 0);
    dfs(1, 1, 0);

    for (int i = 1; i <= m; i++) cin >> spt[i][0];
    for (int s = 1; s < 18; s++) {
        for (int i = 1; i + (1 << s) - 1 <= m; i++) {
            int p = s - 1;
            spt[i][s] = lca(spt[i][p], spt[i + (1 << p)][p]);
        }
    }

    for (int i = 0; i < q; i++) {
        int l, r; cin >> l >> r;
        qry[r].push_back({l, i});
    }

    for (int r = 1; r <= m; r++) {
        update(spt[r][0], r);
        for (auto [l, id] : qry[r])
            ans[id] = freqTable.query(l, r) - depth[queryLCA(l, r)];
    }
    for (int i = 0; i < q; i++) cout << ans[i] << "\n";

    return 0;
}

Compilation message (stderr)

tourism.cpp: In member function 'void BIT::update(int, int)':
tourism.cpp:25:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   25 |         for (; k < tr.size(); k += p(k)) tr[k] += val;
      |                ~~^~~~~~~~~~~
tourism.cpp: In function 'int main()':
tourism.cpp:137:19: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  137 |         for (auto [l, id] : qry[r])
      |                   ^
#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...