问题描述
小 Q 带着一块神奇的石头在星球上漫无目的的游走。突然,他发现了一片开 阔的平地,其上同样散落着一些石头。仔细一数,共有 N 块。小 Q 发现,自己 手中的石头可以通过磁力吸引地上的其它石头,而地上的石头不会互相吸引。这 引起了他的好奇心。
经过调查,小Q建立了一个平面直角坐标系,把自己的坐标设为(x 0 ,y 0 ) (x0,y0) 。 小 Q 发现,地上第 i i 块石头的坐标为 (x i ,y i ) (xi,yi) ,质量为 m i mi ,磁力为 p i pi ,吸引半 径为 r i ri (别问我怎么发现的)。当然,小 Q 手里一开始持有的石头也可以用以上 五个性质描述。
小 Q 决定站在 (x 0 ,y 0 ) (x0,y0) 原地不动,不断地从已经获得的石头中拿起一块, 去吸引其它石头。若一块石头的“质量、与小 Q 的距离”分别不大于“小 Q 正 在拿着的石头的磁力、吸引半径”,则该石头会被吸引到 (x 0 ,y 0 ) (x0,y0) 处。小 Q 想知 道,他最后能获得多少块石头?
输入格式
第一行有 5 个整数 x 0 ,y 0 ,p,r,N x0,y0,p,r,N ,分别表示小 Q 所在的位置,一开始持有的 石头的磁力、吸引半径,以及地上的石头总数。
接下来 N N 行,每行有 5 个整数 x i ,y i ,m i ,p i ,r i xi,yi,mi,pi,ri 。
输出格式
输出一个整数表示答案(不包括小 Q 最初持有的那块石头)。
样例输入
0 0 5 10 5
5 4 7 11 5
-7 1 4 7 8
0 2 13 5 6
2 -3 9 3 4
13 5 1 9 9
样例输出
3
数据规模与约定
对于 30%的数据,1≤N≤1000 1≤N≤1000 。
对于另外 30%的数据,p i =r i pi=ri 。
对于 100%的数据,1≤N≤250000,−10 9 ≤x i ,y i ≤10 9 ,1≤m i ,p i ,r i ≤10 9 1≤N≤250000,−109≤xi,yi≤109,1≤mi,pi,ri≤109 。
时空限制
2s/512MB
题解
分块,在每一个区块中排序
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX_N=700; 4 const int MAX_M=270000; 5 int read(){ 6 int x=0,f=1; 7 char ch=getchar(); 8 while(ch<'0' || ch>'9'){ 9 if(ch=='-'){ 10 f=-1; 11 } 12 ch=getchar(); 13 14 } 15 while(ch>='0' && ch<='9'){ 16 x=x*10+ch-'0'; 17 ch=getchar(); 18 19 } 20 return x*f; 21 } 22 struct node{ 23 double dis; 24 int m,p,r; 25 bool got; 26 }p[MAX_M]; 27 int hd[MAX_M]; 28 int cmp1(const node a,const node b){ 29 return a.dis<b.dis; 30 } 31 int cmp2(const node a,const node b){ 32 return a.m<b.m; 33 } 34 int L[MAX_M],R[MAX_M],tot=0; 35 double D[MAX_M]; 36 struct tool{ 37 int p,r; 38 }t[MAX_M]; 39 int cnt=1; 40 int head=1; 41 int n; 42 int x0,yy0; 43 double dist(int x1,int y1,int x2,int y2){ 44 return sqrt( (double)(x1-x2)*(x1-x2)+(double)(y1-y2)*(y1-y2) ); 45 } 46 int main(){ 47 x0=read(); 48 yy0=read(); 49 int i,j; 50 t[1].p=read(); 51 t[1].r=read(); 52 n=read(); 53 int x,y; 54 for(i=1;i<=n;i++){ 55 x=read(); 56 y=read(); 57 p[i].dis=dist(x,y,x0,yy0); 58 p[i].m=read(); 59 p[i].p=read(); 60 p[i].r=read(); 61 p[i].got=0; 62 } 63 sort(p+1,p+n+1,cmp1); 64 for(i=1;i<=n;i+=MAX_N){ 65 L[++tot]=i; 66 R[tot]=min(n,i+MAX_N-1); 67 D[tot]=p[R[tot]].dis; 68 sort(p+L[tot],p+R[tot]+1,cmp2); 69 } 70 while(head<=cnt){ 71 tool now=t[head]; 72 for(i=1;i<=tot;i++){ 73 if(D[i]>now.r){ 74 for(j=L[i];j<=R[i];j++) 75 if(!p[j].got && p[j].dis<=now.r && p[j].m<=now.p){ 76 t[++cnt].p=p[j].p; 77 t[cnt].r=p[j].r; 78 p[j].got=1; 79 } 80 break; 81 } 82 while(L[i]<=R[i] && p[L[i]].m<=now.p){ 83 if(!p[L[i]].got){ 84 p[L[i]].got=1; 85 t[++cnt].p=p[L[i]].p; 86 t[cnt].r=p[L[i]].r; 87 } 88 L[i]++; 89 } 90 } 91 head++; 92 } 93 cout<<cnt-1; 94 return 0; 95 }