Bubble Cup 11 - Finals [Online Mirror, Div. 1] G.AI robots 主席树
程序员文章站
2022-05-09 21:14:02
...
Description
有n个机器人,每个机器人有三个参数:xi,ri,qi
定义一个机器人i可以看见另一个机器人j为:
xi - ri <= xj <= xi + ri。
现在可以互相看见,且qi差值不超过k的可以谈话,
求有多少对可以谈话。
Sample Input
3 2
3 6 1
7 3 10
10 5 8
Sample Output
1
我们先考虑有序数对(i,j)满足条件,且xj < xi
那么我们需要满足的条件为:
xj + rj >= xi,xi - ri <= xj <= xi + ri,abs(qi - qj) <= k
对于一个我们可以将它拆成两个询问。
1 ~ xi - ri - 1中满足xj + rj >= xi,abs(qi - qj) <= k的点数以及
1 ~ xi中满足xj + rj >= xi,abs(qi - qj) <= k的点数以及
那么我们便可以将他们变成一个询问,按照x排序。
对于一个j的插入,就相当于在xj的位置插入一个东西,那它就变成一个修改。
然后对于另外两个限制条件,首先是q值,因为k <= 20,我们可以考虑按照q来建树,然后就可以直接查询了。
然而会有xi重复的情况你统计一下去一下重即可。
代码卡了卡常,有点丑
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
inline int _min(int x, int y) {return x < y ? x : y;}
inline int _max(int x, int y) {return x > y ? x : y;}
inline int read() {
int s = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * f;
}
struct tnode {
int lc, rc, c;
} t[30 * 310000]; int cnt, rt[610000];
struct node {
int x, l, r, ll, rr, c;
} a[610000], q[610000]; int root[610000];
int tt, xx[610000], rr[610000], Q[610000], v[610000];
int b[610000], pa[610000], hh[610000], pp[610000];
LL ans = 0;
bool cmp(node a, node b) {
if(a.x == b.x) return a.l < b.l;
return a.x < b.x;
}
bool cmp1(node a, node b) {
if(a.x == b.x) return a.c > b.c;
return a.x < b.x;
}
void Link(int &u, int l, int r, int p, int c) {
if(!u) u = ++cnt;
t[u].c++;
if(l == r) return ;
int mid = (l + r) / 2;
if(p <= mid) Link(t[u].lc, l, mid, p, c);
else Link(t[u].rc, mid + 1, r, p, c);
}
int query(int u1, int l, int r, int ll, int rr) {
if(l == ll && r == rr) return t[u1].c;
int mid = (l + r) / 2;
if(rr <= mid) return query(t[u1].lc, l, mid, ll, rr);
else if(ll > mid) return query(t[u1].rc, mid + 1, r, ll, rr);
else return query(t[u1].lc, l, mid, ll, mid) + query(t[u1].rc, mid + 1, r, mid + 1, rr);
}
inline void solve(int l, int r) {
tt++;
for(register int i = l; i <= r; ++i) {
if(v[a[i].c] != tt) v[a[i].c] = tt, root[a[i].c] = 0;
root[a[i].c]++;
}
int sum = 0;
for(register int i = l; i <= r; ++i)
for(int j = a[i].ll; j <= a[i].rr; j++) if(pa[j] && v[j] == tt) sum += root[j];
ans = ans - (sum - (r - l + 1)) / 2 - (r - l + 1);
}
int main() {
int n, k; scanf("%d%d", &n, &k);
for(register int i = 1; i <= n; ++i) {
xx[i] = read(), rr[i] = read(), Q[i] = read();
b[i * 3 - 2] = _max(0, xx[i] - rr[i]);
b[i * 3 - 1] = xx[i];
b[i * 3] = _min(xx[i] + rr[i], 1e9);
} sort(b + 1, b + 3 * n + 1);
int ln = 3 * n + 1;
ln = unique(b + 1, b + ln + 1) - (b + 1);
for(register int i = 1; i <= n; ++i) {
a[i].x = lower_bound(b + 1, b + ln, xx[i]) - b;
a[i].l = lower_bound(b + 1, b + ln, _max(0, xx[i] - rr[i])) - b;
a[i].r = lower_bound(b + 1, b + ln, _min(xx[i] + rr[i], 1e9)) - b;
}
for(register int i = 1; i <= n; ++i) {
b[i * 3 - 2] = _max(0, Q[i] - k);
b[i * 3 - 1] = Q[i];
b[i * 3] = _min(Q[i] + k, 1e9);
} sort(b + 1, b + 3 * n + 1);
int op = 3 * n + 1;
op = unique(b + 1, b + op + 1) - (b + 1);
for(register int i = 1; i <= n; ++i) {
a[i].c = lower_bound(b + 1, b + op, Q[i]) - b;
pa[a[i].c] = 1;
a[i].ll = lower_bound(b + 1, b + op, _max(0, Q[i] - k)) - b;
a[i].rr = lower_bound(b + 1, b + op, _min(Q[i] + k, 1e9)) - b;
} sort(a + 1, a + n + 1, cmp);
int cnt = 0;
for(register int i = 1; i <= n; ++i) {
q[++cnt].x = a[i].l - 1; q[cnt].l = a[i].ll; q[cnt].r = a[i].rr, q[cnt].ll = a[i].x, q[cnt].c = 1;
q[++cnt].x = a[i].x, q[cnt].l = a[i].ll; q[cnt].r = a[i].rr, q[cnt].ll = a[i].x, q[cnt].c = 2;
q[++cnt].x = a[i].x, q[cnt].l = a[i].r, q[cnt].r = a[i].c, q[cnt].c = 3;
} sort(q + 1, q + cnt + 1, cmp1);
int tp1 = 0, tp2 = 0;
ans = 0; int last = 0;
for(register int i = 1; i <= cnt; ++i) {
if(q[i].c == 3) Link(rt[q[i].r], 1, ln, q[i].l, 1);
else {
int tt = 0;
for(register int j = q[i].l; j <= q[i].r; ++j) {
if(!pa[j]) continue;
tt += query(rt[j], 1, ln, q[i].ll, ln);
} if(q[i].c == 1) ans -= tt;
else ans += tt;
}
}
int l = 1;
for(register int i = 1; i <= n; ++i) {
if(i == 1 || a[i].x == a[i - 1].x) continue;
else solve(l, i - 1), l = i;
}
solve(l, n); printf("%lld\n", ans);
return 0;
}
推荐阅读
-
Bubble Cup 11 - Finals [Online Mirror, Div. 2] C. Space Formula
-
Bubble Cup 12 - Finals [Online Mirror, unrated, Div. 1] E. Product Tuples
-
Bubble Cup 11 - Finals [Online Mirror, Div. 1] I. Palindrome Pairs(字符串hash)
-
Bubble Cup 11 - Finals [Online Mirror, Div. 1] B. Space Isaac Hash
-
CodeForces Bubble Cup 11 - Finals [Online Mirror, Div. 2] F题
-
Bubble Cup 11 - Finals [Online Mirror, Div. 1] G.AI robots 主席树
-
Bubble Cup 11 - Finals [Online Mirror, Div. 2] B. Hyperspace Highways(tarjan - 点双连通分量 + LCA)
-
Bubble Cup 11 - Finals [Online Mirror, Div. 2], problem (H) Palindrome Pairs 字符处理优化