제출 #763590

#제출 시각아이디문제언어결과실행 시간메모리
763590anhduc2701Tourism (JOI23_tourism)C++17
28 / 100
5065 ms45712 KiB
/*
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimize("unroll-loops")
*/
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define eb emplace_back
#define PI acos(-1.0)
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define BIT(x, i) (1 & ((x) >> (i)))
#define MASK(x) (1LL << (x))
#define task "tnc"
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep1(i, n) for (int i = 1; i <= (n); i++)
typedef long long ll;
typedef long double ld;
const ll INF = 1e18;
const int maxn = 3e5 + 5;
const int mod = 1e9 + 7;
const int mo = 998244353;
using pi = pair<ll, ll>;
using vi = vector<ll>;
using pii = pair<pair<ll, ll>, ll>;
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
int tin[maxn];
int tout[maxn];
int eu[maxn];
int n, m, q;
int ti = 0;
vector<int> G[maxn];
int h[maxn];
void dfs(int u, int pa)
{
    tin[u] = ++ti;
    eu[ti] = u;
    for (auto v : G[u])
    {
        if (v == pa)
            continue;
        h[v] = h[u] + 1;
        dfs(v, u);
        eu[++ti] = u;
    }
}
pair<int, int> rmq[maxn][19];
void init()
{
    for (int i = 1; i <= ti; i++)
    {
        rmq[i][0] = {tin[eu[i]], eu[i]};
    }
    for (int j = 1; (1 << j) <= ti; j++)
    {
        for (int i = 1; i <= ti; i++)
        {
            rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
        }
    }
}
const int blk = 330;
struct que
{
    int l, r, id;
    que() {}
    que(int _l, int _r, int _id)
    {
        l = _l;
        r = _r;
        id = _id;
    }
    bool operator<(const que &x)
    {
        if (l / blk == x.l / blk)
            return r < x.r;
        return l < x.l;
    }
};
set<int> d;
int cnt[maxn];
int sum = 0;
int LCA(int u, int v)
{
    if (tin[u] > tin[v])
        swap(u, v);
    int k = 31 - __builtin_clz(tin[v] - tin[u] + 1);
    return min(rmq[tin[u]][k], rmq[tin[v] - (1 << k) + 1][k]).se;
}
int calc(int u, int v)
{
    return h[v] - h[LCA(u, v)];
}
void add(int u)
{
    cnt[u]++;
    if (cnt[u] == 1)
    {
        auto k = d.lower_bound(tin[u]);

        if (k != d.end())
        {
            sum += calc(u, eu[(*k)]);
            if (k != d.begin())
            {
                int x = (*k);
                k--;
                sum -= calc(eu[(*k)], eu[x]);
                k++;
            }
        }
        if (k != d.begin())
        {
            k--;
            sum += calc(eu[(*k)], u);
        }
        d.insert(tin[u]);
    }
}

void era(int u)
{
    cnt[u]--;
    if (cnt[u] == 0)
    {
        auto k = d.lower_bound(tin[u]);
        k++;
        int nxt = 0;
        int bef = 0;
        if (k != d.end())
        {
            nxt = (*k);
            sum -= calc(u, eu[nxt]);
        }
        k--;

        if (k != d.begin())
        {
            k--;
            bef = (*k);
            sum -= calc(eu[bef], u);
        }
        if (bef != 0 && nxt != 0)
        {
            sum += calc(eu[bef], eu[nxt]);
        }
        d.erase(tin[u]);
    }
}
vector<que> p;
int ans[maxn];
int c[maxn];
signed main()
{
    cin.tie(0), cout.tie(0)->sync_with_stdio(0);
    cin >> n >> m >> q;
    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        G[u].pb(v);
        G[v].pb(u);
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> c[i];
    }
    dfs(1, -1);
    init();
    for (int i = 1; i <= q; i++)
    {
        int l, r;
        cin >> l >> r;
        p.pb(que(l, r, i));
    }
    sort(p.begin(), p.end());
    int l = 1;
    int r = 0;
    //  cout << calc(7, 4) << "\n";
    for (auto &v : p)
    {

        while (l < v.l)
            era(c[l++]);
        while (l > v.l)
            add(c[--l]);
        while (r > v.r)
            era(c[r--]);
        while (r < v.r)
            add(c[++r]);
        int st = (*d.begin());
        int en = (*d.rbegin());
        ans[v.id] = calc(eu[en], eu[st]) + sum;
    }
    for (int i = 1; i <= q; i++)
    {
        cout << ans[i] + 1 << "\n";
    }
}
#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...