Problem A. Archery Tournament
Time limit: 3 seconds
You were invited to the annual archery tournament. You are going to compete against the best archers
from all of the Northern Eurasia. This year, a new type of competition is introduced, where a shooting
range is dynamic and new targets might appear at any second.
As the shooting range is far enough from you, it can be represented as a 2D plane, where y = 0 is the
ground level. There are some targets in a shape of a circle, and all the targets are standing on the ground.
That means, if a target’s center is (x, y) (y > 0), then its radius is equal to y, so that it touches the line
y = 0. No two targets simultaneously present at the range at any given time intersect (but they may
touch).
Initially, the shooting range is empty. Your participation in this competition can be described as n events:
either a new target appears at the range, or you shoot an arrow at some point at the range. To hit a
target, you must shoot strictly inside the circle (hitting the border does not count). If you shoot and hit
some target, then the target is removed from the range and you are awarded one point.
Input
The first line of the input contains integer n (1 ≤ n ≤ 2·105
). Next n lines describe the events happening
at the tournament. The i-th line contains three integers ti
, xi
, and yi (ti = 1, 2; −109 ≤ xi
, yi ≤ 109
;
yi > 0).
• If ti = 1, then a new target with center (xi
, yi) and radius yi appears at the range.
• If ti = 2, then you perform a shot, which hits the range at (xi
, yi).
Output
For each of your shots, output a separate line with the single integer. If the shot did not hit any target,
print “-1”. If the shot hit a target, print the number of event when that target was added to the range.
Events are numbered starting from 1.
Examples
input output illustration
8
1 0 12
2 -11 22
1 24 10
1 12 3
2 12 12
2 16 14
1 28 15
2 3 6
-1
-1
3
1
×
×
×
-15 -10 -5 0 5 10 15 20 25 30 35
Note
Illustration shows the state of the range after first six events. The rightmost target was hit by the last
shot and is going to be removed.
题意:1是创建靶子,2是打枪 在 (x,y),打中的靶子被移除 考虑在上面大圆下面小圆的情况下,能到达枪的X轴的靶子不会很多,那么可以把靶子的左右区间更新在线段树上,同时树的每一个结点有一个vector存靶子,靶子在一些区间会同时出现,但是内存也就 nlogn 完全是可以的,考虑范围为-1e9~1e9 可以动态开店,也可以离线
#include <bits/stdc++.h>
using namespace std;
int tot;
vector<int> v[200005*20];
int ls[200005*20],rs[200005*20];
int x[200005],y[200005];
int ans;
int check(int x1,int y1,int x2,int y2)
{
if(1ll*(x1-x2)*(x1-x2)+1ll*(y1-y2)*(y1-y2)<1ll*y1*y1) return 1;
return 0;
}
void insert(int &now,int l,int r,int L,int R,int id)
{
if(!now)
now=++tot;
if(L<=l&&R>=r)
{
v[now].push_back(id);
return ;
}
int mid=(l+r)>>1;
if(L<=mid) insert(ls[now],l,mid,L,R,id);
if(R>mid) insert(rs[now],mid+1,r,L,R,id);
}
void ask(int now,int l,int r,int xx,int yy)
{
if(!now) return ;
for(int i=0;i<v[now].size();i++)
if(check(x[v[now][i]],y[v[now][i]],xx,yy))
{
ans=v[now][i];
return ;
}
if(l==r) return ;
int mid=(l+r)>>1;
if(xx<=mid) ask(ls[now],l,mid,xx,yy);
else ask(rs[now],mid+1,r,xx,yy);
}
void del(int now,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
{
vector<int> y;
for(int i=0;i<v[now].size();i++)
if(v[now][i]!=ans) y.push_back(v[now][i]);
v[now]=y;
return ;
}
int mid=(l+r)>>1;
if(L<=mid) del(ls[now],l,mid,L,R);
if(R>mid) del(rs[now],mid+1,r,L,R);
}
int main()
{
int n;
scanf("%d",&n);
int rt=0;
tot=0;
for(int i=1;i<=n;i++){
int t,xx,yy;
scanf("%d%d%d",&t,&xx,&yy);
if(t==1)
x[i]=xx,y[i]=yy,insert(rt,-1e9,1e9,xx-yy,xx+yy,i);
else
{
ans=-1;
ask(rt,-1e9,1e9,xx,yy);
printf("%d\n",ans );
if(ans!=-1) del(rt,-1e9,1e9,x[ans]-y[ans],x[ans]+y[ans]);
}
}
}