2018-ACetic_ACid/AugTrain-11/A
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int T=1<<20, N=2e5+5;
set<int> a[T];
int sz,n,vn;
int v[N*2];
struct point {
int x,y;
point(int x=0,int y=0):x(x),y(y) {}
} p[N];
struct query {
int x,y;
int type;
} q[N];
inline ll sqr(ll x) { return x*x; }
ll dist(const point& p,const point& q)
{
return sqr(p.x-q.x) + sqr(p.y-q.y);
}
int pos(int x) { return lower_bound(v+1,v+vn,x)-v; }
void insert(int x,int y,int val)
{
//printf("ins %d %d %d\n",v[x],v[y],val);
for(x+=sz-1,y+=sz+1;x^y^1;x>>=1,y>>=1) {
if(~x&1) a[x^1].insert(val);
if( y&1) a[y^1].insert(val);
}
}
void erase(int x,int y,int val)
{
for(x+=sz-1,y+=sz+1;x^y^1;x>>=1,y>>=1) {
if(~x&1) a[x^1].erase(val);
if( y&1) a[y^1].erase(val);
}
}
void insert_p(int i)
{
p[i]=point(q[i].x,q[i].y);
int lb=pos(p[i].x-p[i].y), ub=pos(p[i].x+p[i].y);
insert(lb,ub,i);
}
void erase_p(int i)
{
int lb=pos(p[i].x-p[i].y), ub=pos(p[i].x+p[i].y);
erase(lb,ub,i);
}
int check(const point& pt,int s)
{
//printf("check %d %d %d\n",pt.x,pt.y,s);
for(auto i:a[s]) {
if(dist(p[i],pt)<sqr(p[i].y)) return i;
}
return 0;
}
void query(const point& pt)
{
int s=upper_bound(v+1,v+vn,pt.x)-v;
//printf("x=%d %d~%d\n",pt.x,v[s-1],v[s]);
for(s+=sz;s;s>>=1) if(!a[s].empty()) {
int ch=check(pt,s);
if(ch) {
printf("%d\n",ch);
erase_p(ch);
return;
}
}
puts("-1");
}
int main()
{
int i;
scanf("%d",&n);
vn=0;
for(i=1;i<=n;i++) {
scanf("%d%d%d",&q[i].type,&q[i].x,&q[i].y);
if(q[i].type==1) {
v[++vn]=q[i].x-q[i].y;
v[++vn]=q[i].x+q[i].y;
}
}
sort(v+1,v+vn+1);
vn=unique(v+1,v+vn+1)-v;
for(sz=1;sz<=vn;sz<<=1);
for(i=1;i<=n;i++) {
if(q[i].type==1) insert_p(i);
else query(point(q[i].x,q[i].y));
}
}
}}}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int T=1<<20, N=2e5+5;
set<int> a[T];
int sz,n,vn;
int v[N*2];
struct point {
int x,y;
point(int x=0,int y=0):x(x),y(y) {}
} p[N];
struct query {
int x,y;
int type;
} q[N];
inline ll sqr(ll x) { return x*x; }
ll dist(const point& p,const point& q)
{
return sqr(p.x-q.x) + sqr(p.y-q.y);
}
int pos(int x) { return lower_bound(v+1,v+vn,x)-v; }
void insert(int x,int y,int val)
{
//printf("ins %d %d %d\n",v[x],v[y],val);
for(x+=sz-1,y+=sz+1;x^y^1;x>>=1,y>>=1) {
if(~x&1) a[x^1].insert(val);
if( y&1) a[y^1].insert(val);
}
}
void erase(int x,int y,int val)
{
for(x+=sz-1,y+=sz+1;x^y^1;x>>=1,y>>=1) {
if(~x&1) a[x^1].erase(val);
if( y&1) a[y^1].erase(val);
}
}
void insert_p(int i)
{
p[i]=point(q[i].x,q[i].y);
int lb=pos(p[i].x-p[i].y), ub=pos(p[i].x+p[i].y);
insert(lb,ub,i);
}
void erase_p(int i)
{
int lb=pos(p[i].x-p[i].y), ub=pos(p[i].x+p[i].y);
erase(lb,ub,i);
}
int check(const point& pt,int s)
{
//printf("check %d %d %d\n",pt.x,pt.y,s);
for(auto i:a[s]) {
if(dist(p[i],pt)<sqr(p[i].y)) return i;
}
return 0;
}
void query(const point& pt)
{
int s=upper_bound(v+1,v+vn,pt.x)-v;
//printf("x=%d %d~%d\n",pt.x,v[s-1],v[s]);
for(s+=sz;s;s>>=1) if(!a[s].empty()) {
int ch=check(pt,s);
if(ch) {
printf("%d\n",ch);
erase_p(ch);
return;
}
}
puts("-1");
}
int main()
{
int i;
scanf("%d",&n);
vn=0;
for(i=1;i<=n;i++) {
scanf("%d%d%d",&q[i].type,&q[i].x,&q[i].y);
if(q[i].type==1) {
v[++vn]=q[i].x-q[i].y;
v[++vn]=q[i].x+q[i].y;
}
}
sort(v+1,v+vn+1);
vn=unique(v+1,v+vn+1)-v;
for(sz=1;sz<=vn;sz<<=1);
for(i=1;i<=n;i++) {
if(q[i].type==1) insert_p(i);
else query(point(q[i].x,q[i].y));
}
}