题解 [NEERC2017]Archery Tournament
由于这些圆都与
考虑用线段树维护。每个节点开一个 unordered_set,每次修改向 unordered_set 就好。修改的复杂度是
代码:
#include<cstdio>
#include<unordered_set>
#include<algorithm>
const int N=2e5+10;
int n,t[N],x[N],y[N],a[N];
std::unordered_set<int>st[N<<2];
void update(int rt,int l,int r,int ql,int qr,int x)
{
if(ql<=l&&r<=qr){x<0?(st[rt].erase(-x),0):(st[rt].insert(x),0);return;}
int m=(l+r)>>1;
if(ql<=m)update(rt<<1,l,m,ql,qr,x);
if(qr>m)update(rt<<1|1,m+1,r,ql,qr,x);
}
void query(int rt,int l,int r,int p,int &ans)
{
for(int i:st[rt])if(1ll*(x[p]-x[i])*(x[p]-x[i])+1ll*(y[p]-y[i])*(y[p]-y[i])<1ll*y[i]*y[i])ans=i;
if(l==r)return; int m=(l+r)>>1;
x[p]<=a[m]?query(rt<<1,l,m,p,ans):query(rt<<1|1,m+1,r,p,ans);
}
int main()
{
int i,p;scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d%d",&t[i],&x[i],&y[i]),a[i]=x[i];
std::sort(a+1,a+1+n);
for(i=1;i<=n;i++)
t[i]==1?(update(1,1,n,std::lower_bound(a+1,a+1+n,x[i]-y[i])-a,std::upper_bound(a+1,a+1+n,x[i]+y[i])-a-1,i),0):
(p=-1,query(1,1,n,i,p),printf("%d\n",p),(~p)&&(update(1,1,n,std::lower_bound(a+1,a+1+n,x[p]-y[p])-a,std::upper_bound(a+1,a+1+n,x[p]+y[p])-a-1,-p),0));
return 0;
}