Contest Hunter #46 T1 磁力块 [分块]
描述
在一片广袤无垠的原野上,散落着N块磁石。每个磁石的性质可以用一个五元组(x,y,m,p,r)描述,其中x,y表示其坐标,m是磁石的质量,p是磁力,r是吸引半径。若磁石A与磁石B的距离不大于磁石A的吸引半径,并且磁石B的质量不大于磁石A的磁力,那么A可以吸引B。
小取酒带着一块自己的磁石L来到了这篇原野的(x0,y0)处,我们可以视为磁石L的坐标为(x0,y0)。小取酒手持磁石L并保持原地不动,所有可以被L吸引的磁石将会被吸引过来。在每个时刻,他可以选择更换任意一块自己已经获得的磁石(当然也可以是自己最初携带的L磁石)在(x0,y0)处吸引更多的磁石。小取酒想知道,他最多能获得多少块磁石呢?
输入格式
第一行五个整数x0,y0,pL,rL,N,表示小取酒所在的位置,磁石L磁力、吸引半径和原野上散落磁石的个数。
接下来N行每行五个整数x,y,m,p,r,描述一块磁石的性质。
输出格式
输出一个整数,表示最多可以获得的散落磁石个数(不包含最初携带的磁石L)。
样例输入
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。
- 对于100%的数据,1<=N<=250000,-10^9<=x,y<=10^9,1<=m,p,r<=10^9。
将石块按距离分块,每块内按质量排序。挨个尝试用已有的石头吸引剩下的石头即可。
一直觉得分块就是稍有些技巧的暴力……
事实上这题的标解分块还真不如我的花式暴力跑得快23333
花式暴力:http://www.cnblogs.com/SilverNebula/p/5929674.html
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int w=700; 9 const int mxn=270000; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 struct node{ 17 double dis; 18 int m,p,r; 19 bool got; 20 }p[mxn]; 21 int hd[mxn]; 22 int cmpd(const node a,const node b){ 23 return a.dis<b.dis; 24 } 25 int cmpm(const node a,const node b){ 26 return a.m<b.m; 27 } 28 // 29 int L[mxn],R[mxn],tot=0; 30 double D[mxn]; 31 // 32 struct tool{ 33 int p,r; 34 }t[mxn];int cnt=1; 35 int head=1; 36 int n; 37 int x0,yy0; 38 double dist(int x1,int y1,int x2,int y2){ 39 return sqrt( (double)(x1-x2)*(x1-x2)+(double)(y1-y2)*(y1-y2) ); 40 } 41 int main(){ 42 x0=read();yy0=read(); 43 int i,j; 44 t[1].p=read();t[1].r=read(); 45 n=read(); 46 int x,y; 47 for(i=1;i<=n;i++){ 48 x=read();y=read(); 49 p[i].dis=dist(x,y,x0,yy0); 50 p[i].m=read(); p[i].p=read(); p[i].r=read(); 51 p[i].got=0; 52 } 53 sort(p+1,p+n+1,cmpd); 54 for(i=1;i<=n;i+=w){ 55 L[++tot]=i;R[tot]=min(n,i+w-1);D[tot]=p[R[tot]].dis; 56 sort(p+L[tot],p+R[tot]+1,cmpm); 57 } 58 while(head<=cnt){ 59 tool now=t[head]; 60 for(i=1;i<=tot;i++){ 61 if(D[i]>now.r){ 62 for(j=L[i];j<=R[i];j++) 63 if(!p[j].got && p[j].dis<=now.r && p[j].m<=now.p){ 64 t[++cnt].p=p[j].p; 65 t[cnt].r=p[j].r; 66 p[j].got=1; 67 } 68 break; 69 } 70 while(L[i]<=R[i] && p[L[i]].m<=now.p){ 71 if(!p[L[i]].got){ 72 p[L[i]].got=1; 73 t[++cnt].p=p[L[i]].p; 74 t[cnt].r=p[L[i]].r; 75 } 76 L[i]++; 77 } 78 } 79 head++; 80 } 81 printf("%d\n",cnt-1); 82 return 0; 83 }
本文为博主原创文章,转载请注明出处。