首先,代码非常丑陋。不想看的已经退出去了。
其次,错误大概是端点判错。
求救。
WA 94 pts:
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cassert>
#include <utility>
//#define DEBUG 1
using std::vector;
typedef long long ll;
const int N = 200005;
int q, n;
struct Point {
int x, y, id;
void input(const int& _id) {
scanf("%d%d", &x, &y);
id = _id;
}
void output() {
fprintf(stderr, "p[%d] = (%d, %d)\n", id, x, y);
}
};
Point a[N], copy[N], same[N];
int top = 0;
vector<int> G[N];
ll dis(const Point& u, const Point& v) {
return std::abs(u.x - v.x) + std::abs(u.y - v.y);
}
ll dis_sum[N], ring_dis;
bool cmp_x(const Point& u, const Point& v) {
return u.x < v.x;
}
bool cmp_y(const Point& u, const Point& v) {
return u.y < v.y;
}
void add_edge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
}
void build() { // to build edges;
for (int i = 1; i <= n; i++)
copy[i] = a[i];
std::sort(a + 1, a + 1 + n, cmp_x);
a[n + 1] = {-1, -1, -1};
for (int i = 1; i <= n; i++) {
same[++top] = a[i];
if (a[i].x != a[i + 1].x) {
std::sort(same + 1, same + top + 1, cmp_y);
for (int j = 1; j <= top; j += 2)
add_edge(same[j].id, same[j + 1].id);
top = 0;
}
} // the same x;
std::sort(a + 1, a + 1 + n, cmp_y);
for (int i = 1; i <= n; i++) {
same[++top] = a[i];
if (a[i].y != a[i + 1].y) {
std::sort(same + 1, same + top + 1, cmp_x);
for (int j = 1; j <= top; j += 2)
add_edge(same[j].id, same[j + 1].id);
top = 0;
}
} // the same y;
for (int i = 1; i <= n; i++)
a[i] = copy[i];
}
Point ring[N];
int rcnt, id[N]; // id 为从编号映射到在环上的位置
bool vis[N];
void dfs(int u) { // to find the circle;
ring[++rcnt] = a[u];
vis[u] = 1;
for (int v : G[u]) {
if (!vis[v])
dfs(v);
}
}
Point dx[N], dy[N];
typedef std::pair<int, int> piir;
const piir BadPos = {-1, -1};
bool check(int num, int l, int r) {
int pl = std::min(l, r), pr = std::max(l, r);
return (pl <= num && num <= pr);
}
piir check_x(int x, int y) { // 找(x, y)在垂直于 x 轴的边
Point idx = {x, y, 0};
Point* l = std::lower_bound(dx + 1, dx + 1 + n, idx, cmp_x);
if (l->x != x) return BadPos;
Point * r = std::upper_bound(dx + 1, dx + 1 + n, idx, cmp_x);
//#ifdef DEBUG
// fprintf(stderr, "Check_x:: (%d, %d) on dx- %lld to %lld;\n", x, y, l - dx, r - dx - 1);
//#endif
int u = std::lower_bound(l, r, idx, cmp_y)->id;
for (int v : G[u])
if (a[v].x == a[u].x) {
piir res = {u, v};
if (id[u] > id[v]) res = {v, u};
if (res.first == 1 && res.second == ring[n].id)
std::swap(res.first, res.second);
if (!check(y, a[res.first].y, a[res.second].y)) return BadPos;
return res;
}
return BadPos;
}
piir check_y(int x, int y) { // 同上,变为 y 轴
Point idx = {x, y, 0};
Point* l = std::lower_bound(dy + 1, dy + 1 + n, idx, cmp_y);
if (l->y != y) return BadPos;
Point * r = std::upper_bound(dy + 1, dy + 1 + n, idx, cmp_y);
//#ifdef DEBUG
// fprintf(stderr, "Check_y:: (%d, %d) on dx- %lld to %lld;\n", x, y, l - dy, r - dy - 1);
//#endif
int u = std::lower_bound(l, r, idx, cmp_x)->id;
for (int v : G[u])
if (a[v].y == a[u].y) {
piir res = {u, v};
if (id[u] > id[v]) res = {v, u};
if (res.first == 1 && res.second == ring[n].id)
std::swap(res.first, res.second);
if (!check(x, a[res.first].x, a[res.second].x)) return BadPos;
return res;
}
return BadPos;
}
piir find(int x, int y) {
piir r = check_x(x, y), l = check_y(x, y);
#ifdef DEBUG
// fprintf(stderr, "edge(%d %d) or edge(%d %d)\n", r.first, r.second, l.first, l.second);
#endif
if (r != BadPos && (l == BadPos || id[l.first] > id[r.first])) return r;
if (l != BadPos && (r == BadPos || id[r.first] > id[l.first])) return l;
return r;
}
ll ans[N], rans[N];
void add(int l, int r) {
// printf("add %d to %d\n", l, r);
ans[l]++, ans[r + 1]--;
}
void solve() {
for (int i = 1; i <= n; i++)
dx[i] = dy[i] = a[i];
std::sort(dx + 1, dx + 1 + n, cmp_x), dx[n + 1] = {-1, -1, -1};
for (int i = 1, pre = 1; i <= n; i++)
if (dx[i].x != dx[i + 1].x)
std::sort(dx + pre, dx + i + 1, cmp_y), pre = i + 1;
// 给 x 相同的排序
std::sort(dy + 1, dy + 1 + n, cmp_y), dy[n + 1] = {-1, -1, -1};
for (int i = 1, pre = 1; i <= n; i++)
if (dy[i].y != dy[i + 1].y)
std::sort(dy + pre, dy + i + 1, cmp_x), pre = i + 1;
// 同上
for (int rep = 1, x, y, u, v; rep <= q; rep++) {
scanf("%d%d%d%d", &x, &y, &u, &v);
piir f = find(x, y), s = find(u, v);
if (id[f.first] > id[s.first]) std::swap(f, s), std::swap(x, u), std::swap(y, v);
piir sx = {x, y}, sy = {u, v};
if (f.first == s.first && f.second == s.second) {
int pl = f.first, pr = f.second;
piir l = {a[pl].x, a[pl].y};
piir r = {a[pr].x, a[pr].y};
if (sx == l || sy == l) add(id[pl], id[pl]);
if (sx == r || sy == r) add(id[pr], id[pr]);
continue;
}
ll dist = dis_sum[id[s.first]] - dis_sum[id[f.second]] + dis({x, y, 0}, a[f.second]) + dis({u, v, 0}, a[s.first]);
ll rhs = ring_dis - dist;
if (dist < rhs) {
add(id[f.second], id[s.first]);
int pl = f.first;
piir l = {a[pl].x, a[pl].y};
if (sx == l || sy == l) add(id[pl], id[pl]);
int pr = s.second;
l = {a[pr].x, a[pr].y};
if (sx == l || sy == l) add(id[pr], id[pr]);
} else {
add(1, id[f.first]);
int pl = f.second;
piir l = {a[pl].x, a[pl].y};
if (sx == l || sy == l) add(id[pl], id[pl]);
if (s.second != 1)
add(id[s.second], n);
}
}
}
int main() {
//qwq
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d%d", &q, &n);
for (int i = 1; i <= n; i++)
a[i].input(i);
build();
dfs(1);
for (int i = 1; i <= n; i++)
ring_dis += dis(ring[i], ring[(i == n) ? 1 : i + 1]), id[ring[i].id] = i;
for (int i = 1; i <= n + 1; i++)
dis_sum[i] += dis_sum[i - 1] + dis(ring[i], ring[i - 1]);
solve();
for (int i = 1; i <= n; i++)
ans[i] += ans[i - 1];
for (int i = 1; i <= n; i++)
rans[ring[i].id] = ans[i];
for (int i = 1; i <= n; i++)
printf("%lld\n", rans[i]);
return 0;
}