제출 #504018

#제출 시각아이디문제언어결과실행 시간메모리
504018VictorValley (BOI19_valley)C++17
0 / 100
354 ms30148 KiB
// #pragma GCC target ("avx,avx2,fma")
// #pragma GCC optimize ("Ofast,inline") // O1 - O2 - O3 - Os - Ofast
// #pragma GCC optimize ("unroll-loops")
#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define per(i, a, b) for (int i = (b - 1); i >= (a); --i)
#define trav(a, x) for (auto &a : x)

#define all(x) x.begin(), x.end()
#define sz(x) x.size()
#define pb push_back
#define debug(x) cout << #x << " = " << x << endl

#define umap unordered_map
#define uset unordered_set

typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<pll> vpll;

const ll INF = 1e18;

struct Node {
    int lo, hi;
    ll madd = 0, val;
    Node *l, *r;

    Node(int L, int R) : lo(L), hi(R) {
        val = INF;
        if (hi - lo != 1) {
            int mid = (lo + hi) / 2;
            l = new Node(lo, mid);
            r = new Node(mid, hi);
        }
    }

    ll query(int L, int R) {
        // cout<<"L = "<<L<<" R = "<<R<<" lo = "<<lo<<" hi = "<<hi<<" val = "<<val<<endl;
        if (hi <= L || R <= lo) return INF;
        if (L <= lo && hi <= R) return val;

        push();
        return min(l->query(L, R), r->query(L, R));
    }

    void add(int L, int R, ll x) {
        if (hi <= L || R <= lo) return;
        if (L <= lo && hi <= R) {
            madd += x;
            val += x;

        } else {
            push();
            l->add(L, R, x);
            r->add(L, R, x);
            val = min(l->val, r->val);
        }
    }

    void push() {
        if (madd) {
            if (hi - lo != 1) {
                l->add(lo, hi, madd);
                r->add(lo, hi, madd);
            }
            madd = 0;
        }
    }
};

int n, s, q, e, euler_pos[100001], depth[100001], sub_size[100001], queries_sub[100001], cnt = 0, order[100001];
ll dist[100001];
vpll graph[100001];
vector<iii> edges;
vii queries[100001];
vi shop;
string ans[100001];
Node *segtree;

void prep(int u, int p, int cur_depth, int cur_dist) {
    order[cnt] = u;
    euler_pos[u] = cnt++;

    sub_size[u] = 1;
    dist[u] = cur_dist;
    depth[u] = cur_depth;
    
    //cout<<"u = "<<u+1<<" dist = "<<dist[u]<<endl;

    trav(edge, graph[u]) {
        int v, w;
        tie(v, w) = edge;
        if (v != p) {
            prep(v, u, cur_depth + 1, cur_dist + w);
            sub_size[u] += sub_size[v];
            queries_sub[u] += queries_sub[v];
        }
    }
}

void solve(int u, int p) {
    trav(query, queries[u]) {
        int edge, indx;
        tie(edge, indx) = query;

        int a, b, w;
        w = edges[edge].first;
        tie(a, b) = edges[edge].second;
        if (depth[a] > depth[b]) swap(a, b);

        bool work = 1;
        if ((euler_pos[b] <= euler_pos[u] && euler_pos[u] < euler_pos[b] + sub_size[b]) ^ (euler_pos[b] <= euler_pos[e] && euler_pos[e] < euler_pos[b] + sub_size[b])) work = 0;

        if (work)
            ans[indx] = "escaped";
        else {
            ll min_dist;
            if (euler_pos[b] <= euler_pos[u] && euler_pos[u] < euler_pos[b] + sub_size[b]) {
                min_dist = segtree->query(euler_pos[b], euler_pos[b] + sub_size[b]);

            } else {
                min_dist = min(segtree->query(0, euler_pos[b]), segtree->query(euler_pos[b] + sub_size[b], n));
                //rep(i, 0, n) cout << "u = " << i + 1 << " dist = " << segtree->query(euler_pos[i], euler_pos[i] + 1) << endl;
            }
            ans[indx] = to_string(min_dist);
            if (min_dist > 1e15) ans[indx] = "oo";
        }
    }

    trav(edge, graph[u]) {
        int v, w;
        tie(v, w) = edge;
        if (v != p && queries_sub[v]) {
            segtree->add(0, euler_pos[v], w);
            segtree->add(euler_pos[v], euler_pos[v] + sub_size[v], -w);
            segtree->add(euler_pos[v] + sub_size[v], n, w);
            solve(v, u);
            segtree->add(0, euler_pos[v], -w);
            segtree->add(euler_pos[v], euler_pos[v] + sub_size[v], w);
            segtree->add(euler_pos[v] + sub_size[v], n, -w);
        }
    }
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin.exceptions(cin.failbit);

    memset(queries_sub, 0, sizeof(queries_sub));
    cin >> n >> s >> q >> e;
    e--;
    segtree = new Node(0, n);

    rep(i, 0, n - 1) {
        int u, v, w;
        cin >> u >> v >> w;
        edges.pb({w, {--u, --v}});
        graph[u].emplace_back(v, w);
        graph[v].emplace_back(u, w);
    }

    rep(i, 0, s) {
        int u;
        cin >> u;
        shop.pb(u - 1);
    }

    rep(i, 0, q) {
        int edge, u;
        cin >> edge >> u;
        queries[--u].emplace_back(edge - 1, i);
        ++queries_sub[u];
    }

    prep(0, 0, 0, 0);
    trav(u, shop) segtree->add(euler_pos[u], euler_pos[u]+1, dist[u] - INF);
    
    //rep(i, 0, n) cout << "u = " << i + 1 << " dist = " << segtree->query(euler_pos[i], euler_pos[i] + 1) << endl;
    //cout << endl;
    solve(0, 0);
    rep(i, 0, q) cout << ans[i] << endl;
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

valley.cpp: In function 'void solve(int, int)':
valley.cpp:116:19: warning: variable 'w' set but not used [-Wunused-but-set-variable]
  116 |         int a, b, w;
      |                   ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...