题意:有n次操作,每次输入三个数x,y,z,若x为1,表示以(y,z)为圆心画一个与x轴相切的圆(保证画出来的圆一定不相交),若x为0,则问(y,z)这个点在哪个圆上,若不在任何圆上,输出-1;若在某个圆上,输出是第几次操作画的圆,并将圆删去
解题思路:线段树+set,因为圆都是不相交的,并且圆心都是整数,所以圆不会很多
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
#include <ctime>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int n;
int x[200009], y[200009], z[200009];
int a[400009], m, tot;
set<int>s[400009 << 2];
void build(int k, int l, int r)
{
s[k].clear();
if (l == r) return;
int mid = (l + r) >> 1;
build(k << 1, l, mid), build(k << 1 | 1, mid + 1, r);
}
void update(int k, int l, int r, int ll, int rr, int p, int flag)
{
if (l >= ll&r <= rr)
{
if (flag) s[k].insert(p);
else s[k].erase(p);
return;
}
int mid = (l + r) >> 1;
if (mid >= ll) update(k << 1, l, mid, ll, rr, p, flag);
if (mid < rr) update(k << 1 | 1, mid + 1, r, ll, rr, p, flag);
}
int query(int k, int l, int r, int p, int id)
{
if (l <= p&&r >= p)
{
for (set<int>::iterator it = s[k].begin(); it != s[k].end(); it++)
{
int temp = *it;
if (1LL * z[temp] * z[temp] > 1LL * (z[id] - z[temp])*(z[id] - z[temp]) + 1LL * (y[id] - y[temp])*(y[id] - y[temp]))
return temp;
}
}
if (l == r) return -1;
int mid = (l + r) >> 1;
if (p <= mid) return query(k << 1, l, mid, p, id);
else return query(k << 1 | 1, mid + 1, r, p, id);
}
int main()
{
while (~scanf("%d", &n))
{
tot = 1;
for (int i = 1; i <= n; i++)
{
scanf("%d %d %d", &x[i], &y[i], &z[i]);
if (x[i] == 1) a[tot++] = y[i] - z[i], a[tot++] = y[i] + z[i];
else a[tot++] = y[i];
}
sort(a + 1, a + tot);
m = unique(a + 1, a + tot) - a - 1;
build(1, 1, m);
for (int i = 1; i <= n; i++)
{
if (x[i] == 1)
{
int xx = lower_bound(a + 1, a + m + 1, y[i] - z[i]) - a;
int yy = lower_bound(a + 1, a + m + 1, y[i] + z[i]) - a;
update(1, 1, m, xx, yy, i, 1);
}
else
{
int xx = lower_bound(a + 1, a + m + 1, y[i]) - a;
int ans = query(1, 1, m, xx, i);
if (ans != -1)
{
int xx = lower_bound(a + 1, a + m + 1, y[ans] - z[ans]) - a;
int yy = lower_bound(a + 1, a + m + 1, y[ans] + z[ans]) - a;
update(1, 1, m, xx, yy, ans, 0);
}
printf("%d\n", ans);
}
}
}
return 0;
}