Submission #556888

#TimeUsernameProblemLanguageResultExecution timeMemory
556888Tien_NoobValley (BOI19_valley)C++17
0 / 100
598 ms56804 KiB
//Make CSP great again
//Vengeance
#include <bits/stdc++.h>
#define TASK "TESTCODE"
#define Log2(x) 31 - __builtin_clz(x)
using namespace std;
const int N = 1e5 , cbit = 16;
int f[N + 1][cbit + 1], depth[N + 1], l[N + 1], r[N + 1], w[N + 1], sz[N + 1], par[N + 1], timer, n, s, q, e;
long long g[N + 1];
bool visited[N + 1];
set<pair<long long, int> > dp[N + 1];
vector<int> adj[N + 1];
void read()
{
    cin >> n >> s >> q >> e;
    for (int i = 1; i < n; ++ i)
    {
        cin >> l[i] >> r[i] >> w[i];
        adj[l[i]].push_back(i);
        adj[r[i]].push_back(i);
    }
}
void DFS(int u, int p)
{
    for (int x: adj[u])
    {
        int v = l[x] ^ r[x] ^ u;
        if (v == p)
        {
            continue;
        }
        depth[v] = depth[u] + 1;
        g[v] = g[u] + w[x];
        f[v][0] = u;
        for (int i = 1; i <= cbit; ++ i)
        {
            f[v][i] = f[f[v][i - 1]][i - 1];
        }
        DFS(v, u);
    }
}
int LCA(int u, int v)
{
    if (depth[v] < depth[u])
    {
        swap(u, v);
    }
    int k = depth[v] - depth[u];
    for (int i = cbit; i >= 0; -- i)
    {
        if ((k >> i) & 1)
        {
            v = f[v][i];
        }
    }
    if (u == v)
    {
        return u;
    }
    for (int i = cbit; i >= 0; -- i)
    {
        if (f[u][i] != f[v][i])
        {
            u = f[u][i];
            v = f[v][i];
        }
    }
    return f[u][0];
}
long long dis(int u, int v)
{
    int k = LCA(u, v);
    return g[u] + g[v] - 2 * g[k];
}
void CenDFS(int u, int p)
{
    sz[u] = 1;
    for (int x : adj[u])
    {
        int v = l[x] ^ r[x] ^ u;
        if (v == p || visited[v])
        {
            continue;
        }
        CenDFS(v, u);
        sz[u] += sz[v];
    }
}
int FindCentroid(int u, int p, int s)
{
    for (int x : adj[u])
    {
        int v = l[x] ^ r[x] ^ u;
        if (v == p || visited[v])
        {
            continue;
        }
        if (sz[v] > s/2)
        {
            return FindCentroid(v, u, s);
        }
    }
    return u;
}
int BuildCentroid(int u)
{
    CenDFS(u, 0);
    int root = FindCentroid(u, 0, sz[u]);
    visited[root] = true;
    for (int x : adj[root])
    {
        int v = l[x] ^ r[x] ^ root;
        if (visited[v])
        {
            continue;
        }
        par[BuildCentroid(v)] = root;
    }
    return root;
}
void update(int u)
{
    for (int v = u; v > 0; v = par[v])
    {
        dp[v].insert({dis(u, v), u});
    }
}
int nchain = 1, chain[N + 1], pos[N + 1], head[N + 1];
void preHLD(int u, int p)
{
    sz[u] = 1;
    for (int x : adj[u])
    {
        int v = l[x] ^ r[x] ^ u;
        if (v == p)
        {
            continue;
        }
        preHLD(v, u);
        sz[u] += sz[v];
    }
}
struct FenwickTree
{
    int tree[N + 1];
    void add(int pos, int val)
    {
        for (; pos <= n; pos += (pos & (-pos)))
        {
            tree[pos] += val;
        }
    }
    int sum(int pos)
    {
        int ret = 0;
        for (; pos > 0; pos -= (pos & (-pos)))
        {
            ret += tree[pos];
        }
        return ret;
    }
    int sum(int l, int r)
    {
        if (l > r)
        {
            return 0;
        }
        return sum(r) - sum(l - 1);
    }
} tree;
void HLD(int u, int p)
{
    int bigchild = -1;
    chain[u] = nchain;
    pos[u] = ++timer;
    if (head[nchain] == 0)
    {
        head[nchain] = u;
    }
    for (int x : adj[u])
    {
        int v = l[x] ^ r[x] ^ u;
        if (v == p)
        {
            continue;
        }
        if (bigchild == -1 || sz[bigchild] < sz[v])
        {
            bigchild = v;
        }
    }
    if (bigchild != -1)
    {
        HLD(bigchild, u);
    }
    for (int x : adj[u])
    {
        int v = l[x] ^ r[x] ^ u;
        if (v == bigchild || v == p)
        {
            continue;
        }
        ++nchain;
        HLD(v, u);
    }
}
bool reachable(int u, int p)
{
    while(chain[u] != chain[p])
    {
        if (tree.sum(pos[head[chain[u]]], pos[u]) > 0)
        {
            return false;
        }
        u = f[head[chain[u]]][0];
    }
    return tree.sum(pos[p] + 1, pos[u]) == 0;
}
bool reach(int u, int v)
{
    int k = LCA(u, v);
    return reachable(u, k) && reachable(v, k);
}
int get(int u)
{
    long long res = -1;
    for (int v = u; v > 0; v = par[v])
    {
        while(!dp[v].empty() && !reach(dp[v].begin()->second, v))
        {
            dp[v].erase(dp[v].begin());
        }
        if (reach(u, v) && !dp[v].empty())
        {
            if (res == -1 || res > dp[v].begin()->first + dis(u, v))
            {
                res = dp[v].begin()->first + dis(u, v);
            }
        }
    }
    return res;
}
void prepare()
{
    DFS(1, 0);
    par[BuildCentroid(1)] = 0;
    timer = 0;
    preHLD(1, 0);
    HLD(1, 0);
    for (int i = 1; i <= s; ++ i)
    {
        int u;
        cin >> u;
        update(u);
    }
    fill(visited + 1, visited + n, false);
    /*for (int i = 1; i <= n; ++ i)
    {
        cerr << chain[i] << '\n';
    }*/
}
void solve()
{
    prepare();
    while(q--)
    {
        int i, u;
        cin >> i >> u;
        if (!visited[i])
        {
            visited[i] = true;
            if (depth[l[i]] > depth[r[i]])
            {
                swap(l[i], r[i]);
            }
            tree.add(pos[r[i]], 1);
        }
        if (reach(u, e))
        {
            cout << "escaped" << '\n';
            continue;
        }
        long long res = get(u);
        if (res == -1)
        {
            cout << "oo" << '\n';
        }
        else
        {
            cout << res << '\n';
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    if (fopen(TASK".INP", "r"))
    {
        freopen(TASK".INP", "r", stdin);
        //freopen(TASK".OUT", "w", stdout);
    }
    int t = 1;
    bool typetest = false;
    if (typetest)
    {
        cin >> t;
    }
    for (int __ = 1; __ <= t; ++ __)
    {
        //cout << "Case " << __ << ": ";
        read();
        solve();
    }
}

Compilation message (stderr)

valley.cpp: In function 'int main()':
valley.cpp:300:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  300 |         freopen(TASK".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...