Submission #1343979

#TimeUsernameProblemLanguageResultExecution timeMemory
1343979niehTourism (JOI23_tourism)C++17
10 / 100
5093 ms40136 KiB
#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define FOD(i, a, b) for(int i = (a); i >= (b); i--)
#define file(name) if(fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
#define fi first
#define se second
#define el cout << '\n'
#define maxn int(1e5 + 5)

using namespace std;

typedef pair<int, int> pii;

const int LOG = 17;

int n, m, q;

int a[maxn], b[maxn];

int d[maxn], par[maxn][20];

int c[maxn];

vector<int> adj[maxn];

void dfs(int u) {
    for(int v : adj[u]) if(v != par[u][0]) {
        par[v][0] = u;
        d[v] = d[u] + 1;
        dfs(v);
    }
}

namespace subtask2 {
    bool check() {
        return n <= 2000;
    }

    int diff[maxn];

    int lca(int u, int v) {
        if(d[u] < d[v]) swap(u, v);
        int k = d[u] - d[v];
        FOD(i, LOG, 0) if(k >> i & 1) u = par[u][i];
        if(u == v) return u;
        FOD(i, LOG, 0) if(par[u][i] != par[v][i]) u = par[u][i], v = par[v][i];
        return par[u][0];
    }

    void update(int u, int v) {
        int l = lca(u, v);
        diff[u]++;
        diff[v]++;
        diff[l]--;
        diff[par[l][0]]--;
    }

    void dfscalc(int u) {
        for(int v : adj[u]) if(v != par[u][0]) {
            dfscalc(v);
            diff[u] += diff[v];
        }
    }

    void solve() {
        dfs(1);
        FOR(i, 1, LOG)
            FOR(u, 1, n) par[u][i] = par[par[u][i - 1]][i - 1];
        while(q--) {
            int l, r;
            cin >> l >> r;
            if(l == r) {
                cout << 1, el;
                continue;
            }
            FOR(i, 1, n) diff[i] = 0;
            FOR(i, l + 1, r) update(c[i - 1], c[i]);
            dfscalc(1);
            int res = 0;
            FOR(i, 1, n) if(diff[i]) res++;
            cout << res, el;
        }
    }
}

namespace subtask3 {
    bool check() {
        FOR(i, 1, n - 1) if(a[i] != i || b[i] != i + 1) return 0;
        return 1;
    }

    pii st[maxn][20];

    pii combine(pii &A, pii &B) {
        return { min(A.fi, B.fi), max(A.se, B.se) };
    }

    pii get(int l, int r) {
        int k = __lg(r - l + 1);
        return combine(st[l][k], st[r - (1 << k) + 1][k]);
    }

    void solve() {
        FOR(i, 1, m) st[i][0] = {c[i], c[i]};
        FOR(j, 1, LOG)
            FOR(i, 1, m - (1 << j) + 1)
                st[i][j] = combine(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        while(q--) {
            int l, r;
            cin >> l >> r;
            pii res = get(l, r);
            cout << res.se - res.fi + 1, el;
        }
    }
}

namespace subtask5 {
    bool check() {
        FOR(i, 1, n - 1) if(a[i] != (i + 1) / 2 || b[i] != i + 1) return 0;
        return 1;
    }

    int val[maxn], res[maxn];

    int t[maxn];

    vector<pii> Q[maxn];

    void update(int x, int v) {
        for(; x; x -= x & -x) t[x] += v;
    }

    int get(int x) {
        int res = 0;
        for(; x <= m; x += x & -x) res += t[x];
        return res;
    }

    void change(int u, int x) {
        if(val[u]) update(val[u], -1);
        val[u] = x;
        update(val[u], 1);
    }

    void updatePath(int u, int v, int x) {
        if(d[u] < d[v]) swap(u, v);
        change(u, x);
        change(v, x);
        while(d[u] != d[v]) {
            u = par[u][0];
            change(u, x);
        }
        if(u == v) return;
        while(par[u][0] != par[v][0]) {
            u = par[u][0];
            v = par[v][0];
            change(u, x);
            change(v, x);
        }
        change(par[u][0], x);
    }

    void solve() {
        FOR(i, 1, q) {
            int l, r;
            cin >> l >> r;
            if(l == r) {
                res[i] = 1;
                continue;
            }
            Q[r].push_back({ l, i });
        }
        FOR(i, 2, m) {
            updatePath(c[i - 1], c[i], i - 1);
            for(pii x : Q[i])
                res[x.se] = get(x.fi);
        }
        FOR(i, 1, q) cout << res[i], el;
    }
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n >> m >> q;
    FOR(i, 1, n - 1) {
        cin >> a[i] >> b[i];
        adj[a[i]].push_back(b[i]);
        adj[b[i]].push_back(a[i]);
    }
    FOR(i, 1, m) cin >> c[i];
    dfs(1);
    if(subtask2::check()) return subtask2::solve(), 0;
    if(subtask3::check()) return subtask3::solve(), 0;
    if(subtask5::check()) return subtask5::solve(), 0;
    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...