Submission #1265379

#TimeUsernameProblemLanguageResultExecution timeMemory
1265379quangminh412Tourism (JOI23_tourism)C++17
28 / 100
5090 ms19344 KiB
/*
  Ben Watson

  Quang Minh MasterDDDDD
*/

#include <bits/stdc++.h>
using namespace std;

#define ll long long

const string name = "test";

void solve();
signed main()
{
    if (fopen((name + ".inp").c_str(), "r"))
    {
        freopen((name + ".inp").c_str(), "r", stdin);
        freopen((name + ".out").c_str(), "w", stdout);
    }
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    solve();

    return 0;
}

// main program
const int maxn = 1e5 + 1;
const int maxbit = 17;
const int N = 316;

vector<int> adj[maxn];
int in[maxn], out[maxn], rev[maxn];
int par[maxbit][maxn], d[maxn], c[maxn];
int n, m, q;

int timeDFS = 0;
void DFS(int u, int p = -1)
{
    in[u] = ++timeDFS;
    rev[timeDFS] = u;
    for (int v : adj[u])
    {
        if (v == p)
            continue;

        d[v] = d[u] + 1;
        par[0][v] = u;
        for (int i = 1; i < maxbit; i++)
            par[i][v] = par[i - 1][par[i - 1][v]];
        DFS(v, u);
    }
    out[u] = timeDFS;
}

int LCA(int u, int v)
{
    if (d[u] < d[v])
        swap(u, v);
    int k = d[u] - d[v];
    for (int i = 0; i < maxbit; i++)
        if (k >> i & 1)
            u = par[i][u];
    if (u == v) return u;
    for (int i = maxbit - 1; i >= 0; i--)
        if (par[i][u] != par[i][v])
        {
            u = par[i][u];
            v = par[i][v];
        }
    return par[0][u];
}

// Mo's algorithm
struct Query
{
    int l, r;
    int id;

    Query() = default;
    Query(int l, int r, int id) : l(l), r(r), id(id) {};
    bool operator < (const Query& other) const
    {
        if (l / N == other.l / N)
            return ((l / N) % 2 == 1 ? r < other.r : r > other.r);
        return l / N < other.l / N;
    }
};
vector<Query> queries;

ll res = 0;
multiset<int> ms;

void add(int u)
{
    // RIGHT
    int L = -1, R = -1;
    auto it = ms.lower_bound(in[u]);
    if (it != ms.end())
    {
        R = rev[*it];
        res -= d[LCA(u, R)];
    }
    // LEFT
    if (it != ms.begin())
    {
        it--;
        L = rev[*it];
        res -= d[LCA(u, L)];
    }

    if (L != -1 && R != -1)
        res += d[LCA(L, R)];

    res += d[u];
    ms.insert(in[u]);
}

void del(int u)
{
    res -= d[u];
    ms.erase(ms.find(in[u]));

    // RIGHT
    int L = -1, R = -1;
    auto it = ms.lower_bound(in[u]);
    if (it != ms.end())
    {
        R = rev[*it];
        res += d[LCA(u, R)];
    }
    // LEFT
    if (it != ms.begin())
    {
        it--;
        L = rev[*it];
        res += d[LCA(u, L)];
    }

    if (L != -1 && R != -1)
        res -= d[LCA(L, R)];
}

void Mo()
{
    sort(queries.begin(), queries.end());
    int curl = queries[0].l, curr = queries[0].l;
    vector<int> ans(q, 0);
    add(c[curl]);

    for (Query &Q : queries)
    {
        int l = Q.l, r = Q.r, id = Q.id;

        while (l < curl) { add(c[--curl]); }
        while (curr < r) { add(c[++curr]); }
        while (curl < l) { del(c[curl++]); }
        while (r < curr) { del(c[curr--]); }

        int u = rev[*ms.begin()], v = rev[*prev(ms.end())];
        ans[id] = res - d[LCA(u, v)] + 1;
    }

    for (int i = 0; i < q; i++)
        cout << ans[i] << '\n';
}

void solve()
{
    cin >> n >> m >> q;
    for (int i = 1; i < n; i++)
    {
        int u, v; cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i = 1; i <= m; i++)
        cin >> c[i];

    DFS(1);

    for (int i = 0; i < q; i++)
    {
        int l, r; cin >> l >> r;

        queries.push_back(Query(l, r, i));
    }

    Mo();
}

Compilation message (stderr)

tourism.cpp: In function 'int main()':
tourism.cpp:19:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   19 |         freopen((name + ".inp").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tourism.cpp:20:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   20 |         freopen((name + ".out").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...