版权声明:转载请注明原出处啦QAQ(虽然应该也没人转载): https://blog.csdn.net/hzk_cpp/article/details/89889638
题目:CH#46A.
题目大意:有一个元素
和其它
个元素
.现在维护一个集合初始只有元素
,然后对于集合中每一个元素
可以把所有满足条件的
取入集合.问集合稳定后的元素个数
.
条件为:
.
这道题的运行过程完全就是bfs的板子,所以直接用bfs来模拟即可把问题转化为一个元素会让哪些元素加入集合.
为了解决这个问题,我们先把所有元素按照 排序,现在我们会发现所有满足 的元素 一定在一个左端点为1的区间内了.
那么如何找出这之中那些满足第一个条件的元素并删除呢?我们在把这个排好序的序列分块,每一块的内部再按照 排序,然后每次查询整块的时候从开头开始删除(肯定是包含块开头连续的一段会被删除),不在整块内则暴力删除,这样做可以保证总时间复杂度为 …
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=250000,G=500;
LL sqr(LL a){return a*a;}
int sx,sy,x,y,n;
struct node{
int m,p;
LL l,r;
}a[N+9];
bool cmp1(const node &a,const node &b){return a.m<b.m;}
bool cmp2(const node &a,const node &b){return a.l<b.l;}
struct block{
int l,r,ca,now;
node a[G+9];
}bl[G+9];
int cb,siz,bel[N+9],ans;
void Build(int n){
siz=500;
while (bl[cb].r<n){
++cb;
bl[cb].l=bl[cb-1].r+1;bl[cb].r=min(bl[cb].l+siz-1,n);
for (int i=bl[cb].l;i<=bl[cb].r;++i){
bel[i]=cb;
bl[cb].a[++bl[cb].ca]=a[i];
}
sort(bl[cb].a+1,bl[cb].a+1+bl[cb].ca,cmp2);
}
}
queue<node>q;
void Bfs(node s){
q.push(s);
node t;
int k,lst;
while (!q.empty()){
t=q.front();q.pop();
++ans;
for (k=0;a[bl[k+1].r].m<=t.p&&k<=cb;++k);
for (int i=1;i<=k;++i){
for (;bl[i].now<bl[i].ca;++bl[i].now)
if (bl[i].a[bl[i].now+1].l<=t.r) q.push(bl[i].a[bl[i].now+1]);
else break;
}
int lst=0;
for (int i=bl[k+1].now+1;i<=bl[k+1].ca;++i)
if (bl[k+1].a[i].m<=t.p&&bl[k+1].a[i].l<=t.r) q.push(bl[k+1].a[i]);
else bl[k+1].a[++lst]=bl[k+1].a[i];
bl[k+1].ca=lst;bl[k+1].now=0;
}
}
Abigail into(){
scanf("%d%d%d%lld%d",&sx,&sy,&a[0].p,&a[0].r,&n);
a[0].r=sqr(a[0].r);
for (int i=1;i<=n;++i){
scanf("%d%d%d%d%lld",&x,&y,&a[i].m,&a[i].p,&a[i].r);
a[i].r=sqr(a[i].r);
a[i].l=sqr((LL)x-sx)+sqr((LL)y-sy);
}
}
Abigail work(){
sort(a+1,a+1+n,cmp1);
Build(n);
Bfs(a[0]);
}
Abigail outo(){
printf("%d\n",ans-1);
}
int main(){
into();
work();
outo();
return 0;
}