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';
}
}