A - Archery Tournament 动态开点+vecotor 神仙题
存图还是像矩形一样的存,每个节点存所在区级内部的圆的编号,然后暴力判断,开始我也有这个想法,但是。。。这TM也能过。。。仔细想想,貌似好像是可以过,时间复杂度玄学无法证明。。。。
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<set> #include<vector> #define LL long long using namespace std; const int maxx = 2e5+6; vector<int>v[maxx*20]; int xx[maxx]; int yy[maxx]; struct node { int l,r; } tree[maxx*20]; int cnt; int ans; bool check(int x1,int y1,int x2,int y2) { return 1LL*(x1-x2)*(x1-x2)+1LL*(y1-y2)*(y1-y2)<1LL*y1*y1; } void buildtree(int &rt,int l,int r,int L,int R,int id) { if (!rt) { cnt++; rt=cnt; } if (L<=l && r<=R) { v[rt].push_back(id); return ; } int mid=(l+r)>>1; if (L<=mid) { buildtree(tree[rt].l,l,mid,L,R,id); } if (R>mid) { buildtree(tree[rt].r,mid+1,r,L,R,id); } } void query(int rt,int l,int r,int x,int y) { if (!rt)return; for (auto it:v[rt]) { if(check(xx[it],yy[it],x,y)) { ans=it; return ; } } if (l==r) { return ; } int mid=(l+r)>>1; if (x<=mid) { query(tree[rt].l,l,mid,x,y); } else { query(tree[rt].r,mid+1,r,x,y); } } void update(int rt,int l,int r,int ul,int ur,int id) { if (ul>ur)return; if (ul<=l && r<=ur) { vector<int>tmp; for (auto it:v[rt]) { if (it!=id) { tmp.push_back(it); } } v[rt]=tmp; return ; } int mid=(l+r)>>1; if (ul<=mid) { update(tree[rt].l,l,mid,ul,ur,id); } if (ur>mid) { update(tree[rt].r,mid+1,r,ul,ur,id); } } int main() { int t,op; int rt; while(~scanf("%d",&t)) { cnt=0; rt=0; for (int i=1; i<=t; i++) { scanf("%d%d%d",&op,&xx[i],&yy[i]); if (op==1) { buildtree(rt,-1e9,1e9,xx[i]-yy[i],xx[i]+yy[i],i); } else { ans=-1; query(rt,-1e9,1e9,xx[i],yy[i]); printf("%d\n",ans); if (ans!=-1) { update(rt,-1e9,1e9,xx[ans]-yy[ans],xx[ans]+yy[ans],ans); } } } } return 0; }
有不懂欢迎咨询
QQ:1326487164(添加时记得备注)