JOISC2014A baga上学

猫猫大失败。

知州所中,我是个三百。模拟赛 T1,口湖线段树,空间开小,遂卒。

首先注意到每一条边只会走一次,那么按照起点开始时间排序之后,走过的边一定是它的子序列。

于是我们对每个点开一个线段树,表示要在这个时刻之前到达这个点最晚要什么时候出发。直接更新即可,最后查询在 \(n\) 号点的线段树上查。

//        No mind to think.
//
//        No will to break.
//
//        No voice to cry suffering.
//
//        Born of God and Void.
//
//        You shall seal the blinding light that plagues their dreams.
//
//        You are the Vessel.
//
//        You are the Hollow Knight.
#ifdef N2
#define _GLIBCXX_DEBUG
#define LOG(...) fprintf(stderr, __VA_ARGS__)
#else 
#define LOG(...)
#endif
#define syncoff ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 3e5 + 10;
const int maxl = maxm * 50;
const int rinf = 9e7;
template<typename _Tp> constexpr inline void Getmin(_Tp &x, _Tp y) {if(x > y) x = y;}
template<typename _Tp> constexpr inline void Getmax(_Tp &x, _Tp y) {if(x < y) x = y;}
class SegTree {//does not support range query
public:
    static int tr[maxl], lc[maxl], rc[maxl], cnt;
    int rt;
    int __new() {
        cnt++;
        tr[cnt] = -1;
        return cnt; 
    }
    void __modify(int &k, int l, int r, int L, int R, int val) {
        if(!k) k = __new();
        if(L <= l && r <= R) {
            Getmax(tr[k], val);
            return;
        }
        int mid = (l + r) >> 1;
        if(L <= mid) __modify(lc[k], l, mid, L, R, val);
        if(R > mid) __modify(rc[k], mid + 1, r, L, R, val);
    }
    void modify(int L, int R, int val) {__modify(rt, 0, rinf, L, R, val);}
    void __query(int k, int l, int r, int addr, int& res) {
        if(!k) return;
        Getmax(res, tr[k]);
        if(l == r) return;
        int mid = (l + r) >> 1;
        if(addr <= mid) __query(lc[k], l, mid, addr, res);
        else __query(rc[k], mid + 1, r, addr, res);
    }
    int query(int addr) {
        int res = -1;
        __query(rt, 0, rinf, addr, res);
        return res;
    }
}sgt[maxn];
int SegTree::tr[maxl], SegTree::lc[maxl], SegTree::rc[maxl], SegTree::cnt = 0;
class Edge {
public:
    int u, v, a, b;
    Edge() = default;
    Edge(int u, int v, int a, int b) : u(u), v(v), a(a), b(b) {}
};
vector<Edge> e;
int n, m, q;
int main() {
    syncoff;
    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        int u, v, a, b;
        cin >> u >> v >> a >> b;
        if(v == 1) continue;
        e.emplace_back(u, v, a, b);
    }
    sort(e.begin(), e.end(), [](Edge a, Edge b){return a.a < b.a;});
    for(auto cur : e) {
        // LOG("%d %d %d %d\n", cur.u, cur.v, cur.a, cur.b);
        if(cur.u == 1) {
            sgt[cur.v].modify(cur.b, rinf, cur.a);
            continue;
        }
        int x = sgt[cur.u].query(cur.a);
        sgt[cur.v].modify(cur.b, rinf, x);
    }
    // for(int i = 1; i <= n; i++) {
    //     for(int j = 0; j <= 10; j++) {
    //         LOG("%d ", sgt[i].query(j));
    //     }
    //     LOG("\n");
    // }
    cin >> q;
    while(q--) {
        int l;
        cin >> l;
        cout << sgt[n].query(l) << '\n';
    }
}
posted @ 2023-10-28 15:54  N2MENT  阅读(22)  评论(0)    收藏  举报