为什么编号改为从 1 ~ n+q 就能过
正确代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N = 5e5 + 5;
const int V = 1e6 + 5;
const int inf = 0x3f3f3f3f;
struct Node {
int x, y, opt, id;
} a[N << 1], tmp[N << 1], b[N << 1];
int n, q, tot, len, ans[N << 1];
struct bit {
int tr[V];
inline int lowbit(int x) {
return x & -x;
}
inline void update(int p, int v) {
while (p <= len) {
tr[p] = max(tr[p], v);
p += lowbit(p);
}
}
inline int query(int x) {
int res = -inf;
while (x) {
res = max(res, tr[x]);
x -= lowbit(x);
}
return res;
}
inline void clear(int x) {
while (x <= len) {
tr[x] = -inf;
x += lowbit(x);
}
}
void init() {
for (int i = 1; i <= len; i++) tr[i] = -inf;
}
} T;
inline void cdq(int l, int r) {
if (l == r) return ;
int mid = (l + r) >> 1;
cdq(l, mid), cdq(mid + 1, r);
int p = l, q = mid + 1, pos = l;
while (p <= mid && q <= r) {
if (b[p].x <= b[q].x) {
if (b[p].opt == 1) T.update(b[p].y, b[p].x + b[p].y);
tmp[pos++] = b[p++];
} else {
if (b[q].opt == 2) ans[b[q].id] = min(ans[b[q].id], b[q].x + b[q].y - T.query(b[q].y));
tmp[pos++] = b[q++];
}
}
while (p <= mid) tmp[pos++] = b[p++];
while (q <= r) {
if (b[q].opt == 2) ans[b[q].id] = min(ans[b[q].id], b[q].x + b[q].y - T.query(b[q].y));
tmp[pos++] = b[q++];
}
for (int i = l; i <= mid; i++) if (b[i].opt == 1) T.clear(b[i].y);
for (int i = l; i <= r; i++) b[i] = tmp[i];
}
inline void solve(int rx, int ry) {
T.init();
for (int i = 1; i <= tot; i++) {
b[i] = a[i];
if (rx) b[i].x = len - b[i].x;
if (ry) b[i].y = len - b[i].y;
}
cdq(1, tot);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> q;
for (int i = 1, x, y; i <= n; i++) {
cin >> x >> y;
a[++tot] = {++x, ++y, 1, i};// 这里是i
len = max(len, max(x, y));
}
for (int i = n + 1, opt, x, y; i <= n + q; i++) { //从n + 1 ~ n + q
cin >> opt >> x >> y;
a[++tot] = {++x, ++y, opt, i};
len = max(len, max(x, y));
ans[i] = inf;
}
len++;
solve(0, 0), solve(0, 1), solve(1, 0), solve(1, 1);
for (int i = 1; i <= tot; i++) if (a[i].opt == 2) cout << ans[i] << endl;
return 0;
}
原代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N = 5e5 + 5;
const int V = 1e6 + 5;
const int inf = 0x3f3f3f3f;
struct Node {
int x, y, opt, id;
} a[N << 1], tmp[N << 1], b[N << 1];
int n, q, tot, len, ans[N << 1];
struct bit {
int tr[V];
inline int lowbit(int x) {
return x & -x;
}
inline void update(int p, int v) {
while (p <= len) {
tr[p] = max(tr[p], v);
p += lowbit(p);
}
}
inline int query(int x) {
int res = -inf;
while (x) {
res = max(res, tr[x]);
x -= lowbit(x);
}
return res;
}
inline void clear(int x) {
while (x <= len) {
tr[x] = -inf;
x += lowbit(x);
}
}
void init() {
for (int i = 1; i <= len; i++) tr[i] = -inf;
}
} T;
inline void cdq(int l, int r) {
if (l == r) return ;
int mid = (l + r) >> 1;
cdq(l, mid), cdq(mid + 1, r);
int p = l, q = mid + 1, pos = l;
while (p <= mid && q <= r) {
if (b[p].x <= b[q].x) {
if (b[p].opt == 1) T.update(b[p].y, b[p].x + b[p].y);
tmp[pos++] = b[p++];
} else {
if (b[q].opt == 2) ans[b[q].id] = min(ans[b[q].id], b[q].x + b[q].y - T.query(b[q].y));
tmp[pos++] = b[q++];
}
}
while (p <= mid) tmp[pos++] = b[p++];
while (q <= r) {
if (b[q].opt == 2) ans[b[q].id] = min(ans[b[q].id], b[q].x + b[q].y - T.query(b[q].y));
tmp[pos++] = b[q++];
}
for (int i = l; i <= mid; i++) if (b[i].opt == 1) T.clear(b[i].y);
for (int i = l; i <= r; i++) b[i] = tmp[i];
}
inline void solve(int rx, int ry) {
T.init();
for (int i = 1; i <= tot; i++) {
b[i] = a[i];
if (rx) b[i].x = len - b[i].x;
if (ry) b[i].y = len - b[i].y;
}
cdq(1, tot);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> q;
for (int i = 1, x, y; i <= n; i++) {
cin >> x >> y;
a[++tot] = {++x, ++y, 1, 0};//这里改为0
len = max(len, max(x, y));
}
for (int i = 1, opt, x, y; i <= q; i++) { // 从 1 ~ q
cin >> opt >> x >> y;
a[++tot] = {++x, ++y, opt, i};
len = max(len, max(x, y));
ans[i] = inf;
}
len++;
solve(0, 0), solve(0, 1), solve(1, 0), solve(1, 1);
for (int i = 1; i <= tot; i++) if (a[i].opt == 2) cout << ans[i] << endl;
return 0;
}