题目链接:https://vjudge.net/problem/Gym-101630A
题目大意:
有\(n\)个操作,每次输入\(t\) \(x\) \(y\)\((t=1,2; -10^9 \le x,y \le 10^9; y > 0)\). 当\(t=1\),在坐标平面上立一个圆心在\(x,y\),半径为\(y\)的圆形靶子。当\(t=2\),往点\(x,y\)射一箭,如果在这个点上有靶子,则输出这个靶子是在第几次操作中出现的,并把这个靶子销毁;如果这个点上没有靶子,则输出\("-1"\)。
知识点: 线段树、离散化
解题思路:
首先,肯定要离散化处理数据。然后用线段树套\(<set>\)(目的是方便删除操作)维护区间中有什么靶子。更新和删除的时候只要找到合适的区间就可以进行操作然后\(return\),不用\(push\) \(up\)或\(push\) \(down\),查询的时候则直到找到合适的靶子或者\(l==r\)为止。
AC代码:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 typedef pair<int,int> P; 7 typedef long long ll; 8 const int maxn=2e5+3; 9 10 struct Input{ 11 int t; 12 ll x,y; 13 }inp[maxn]; 14 ll xs[maxn<<1]; 15 map<ll,int> ind; 16 set<int> tree[maxn<<3]; 17 void update(int L,int R,int c,int l,int r,int rt){ 18 if(L<=l&&r<=R){ 19 tree[rt].insert(c); 20 return; 21 } 22 int m=(l+r)>>1; 23 if(L<=m) update(L,R,c,lson); 24 if(R>m) update(L,R,c,rson); 25 } 26 void era(int L,int R,int c,int l,int r,int rt){ 27 if(L<=l&&r<=R){ 28 tree[rt].erase(c); 29 return; 30 } 31 int m=(l+r)>>1; 32 if(L<=m) era(L,R,c,lson); 33 if(R>m) era(L,R,c,rson); 34 } 35 int query(int pos,int _x,int _y,int l,int r,int rt){ 36 if(l<=pos&&pos<=r){ 37 set<int>::iterator it=tree[rt].begin(); 38 for(;it!=tree[rt].end();it++){ 39 int now=*it; 40 if((inp[now].x-_x)*(inp[now].x-_x)+(inp[now].y-_y)*(inp[now].y-_y)<inp[now].y*inp[now].y) 41 return now; 42 } 43 } 44 if(l==r) return -1; 45 int m=(l+r)>>1; 46 if(pos<=m) return query(pos,_x,_y,lson); 47 else return query(pos,_x,_y,rson); 48 } 49 int main(){ 50 // freopen("in.txt","r",stdin); 51 int n,cnt=0; 52 scanf("%d",&n); 53 for(int i=1;i<=n;i++){ 54 scanf("%d%lld%lld",&inp[i].t,&inp[i].x,&inp[i].y); 55 if(inp[i].t==1) 56 xs[cnt++]=inp[i].x-inp[i].y,xs[cnt++]=inp[i].x+inp[i].y; 57 } 58 sort(xs,xs+cnt); 59 int m=unique(xs,xs+cnt)-xs; 60 for(int i=0;i<m;i++){ 61 ind[xs[i]]=i; 62 } 63 for(int i=1;i<=n;i++){ 64 if(inp[i].t==1) 65 update(ind[inp[i].x-inp[i].y]+1,ind[inp[i].x+inp[i].y],i,1,m-1,1); 66 else{ 67 int pos=-1; 68 int l=1,r=m-1; 69 while(l<=r){ 70 int mid=(l+r)>>1; 71 if(xs[mid-1]>inp[i].x) r=mid-1; 72 else if(xs[mid]<inp[i].x) l=mid+1; 73 else{ 74 pos=mid; 75 break; 76 } 77 } 78 if(pos==-1) printf("-1\n"); 79 else{ 80 int ret=query(pos,inp[i].x,inp[i].y,1,m-1,1); 81 if(ret==-1) 82 printf("-1\n"); 83 else{ 84 printf("%d\n",ret); 85 era(ind[inp[ret].x-inp[ret].y]+1,ind[inp[ret].x+inp[ret].y],ret,1,m-1,1); 86 } 87 } 88 } 89 } 90 return 0; 91 }