# 「NOI2019d2t1」弹跳

## $Description$：

$m \ (m \leq 1.5 \times 10 ^ 5)$ 次连边，每次连边长度为 $t_i \ (1 \leq t_i \leq 10^4)$，以第 $p_i$ 个整点为起点向坐标满足 $l_i \leq x \leq r_i, \ d_i \leq y \leq u_i$ 的所有点连边。

$1$ 号点为起点的单元最短路。

## $Source$：

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 7e4 + 5;

struct city {
int x, y;
} a[N];

struct edge {
int p, t, l, r, d, u;
} b[N * 3];

int n, m, w, h;
int dis[N];

bool vis[N * 3];

std::vector<int> s[N];

typedef std::pair<int, int> pii;

std::priority_queue<pii> q;

std::queue<int> tmp;

struct segment_tree {
std::set<pii> t[N << 2];

void insert(int id_a, int tl = 1, int tr = w, int p = 1) {
t[p].insert(pii(a[id_a].y, id_a));
if (tl == tr)
return ;
int mid = (tl + tr) >> 1;
if (mid >= a[id_a].x)
insert(id_a, tl, mid, p << 1);
else
insert(id_a, mid + 1, tr, p << 1 | 1);
}

void remove(int id_a, int tl = 1, int tr = w, int p = 1) {
t[p].erase(pii(a[id_a].y, id_a));
if (tl == tr)
return ;
int mid = (tl + tr) >> 1;
if (mid >= a[id_a].x)
remove(id_a, tl, mid, p << 1);
else
remove(id_a, mid + 1, tr, p << 1 | 1);
}

void modify(int d, int id_b, int tl = 1, int tr = w, int p = 1) {
if (b[id_b].l <= tl && tr <= b[id_b].r) {
std::set<pii>::iterator x = std::lower_bound(t[p].begin(), t[p].end(), pii(b[id_b].d, 0));
for (; x != t[p].end() && x->first <= b[id_b].u; ++x) {
dis[x->second] = d;
for (unsigned i = 0; i < s[x->second].size(); ++i)
if (!vis[s[x->second][i]])
q.push(pii(-d - b[s[x->second][i]].t, s[x->second][i]));
tmp.push(x->second);
}
for (; !tmp.empty(); remove(tmp.front()), tmp.pop());
return ;
}
int mid = (tl + tr) >> 1;
if (mid >= b[id_b].l)
modify(d, id_b, tl, mid, p << 1);
if (mid < b[id_b].r)
modify(d, id_b, mid + 1, tr, p << 1 | 1);
}

} T;

int main() {
//freopen("in", "r", stdin);
n = in(), m = in(), w = in(), h = in();
for (int i = 1; i <= n; ++i)
a[i] = (city){in(), in()};
for (int i = 1; i <= m; ++i) {
b[i] = (edge){in(), in(), in(), in(), in(), in()};
s[b[i].p].push_back(i);
}
for (int i = 2; i <= n; ++i)
T.insert(i);
for (unsigned i = 0; i < s[1].size(); ++i)
q.push(pii(-b[s[1][i]].t, s[1][i]));
while (!q.empty()) {
int d = q.top().first, u = q.top().second;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
T.modify(-d, u);
}
for (int i = 2; i <= n; ++i)
printf("%d\n", dis[i]);
return 0;
}

posted @ 2019-09-15 00:02  15owzLy1  阅读(125)  评论(1编辑  收藏