BZOJ3053: The Closest M Points
题解:
我们可以事先在堆里放入插入m个inf然后不断的比较当前值与堆首元素的大小,如果小于的话进入。
估计函数也可以随便写写。。。
query的时候貌似不用保留dir。。。
return 0写在 while 里面我也是醉了。。。
不用开long long为什么大家都开了。。。
k-d tree助我进第一版
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 2100000000 13 #define maxn 100000+5 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define sqr(x) (x)*(x) 18 #define pa pair<int,int> 19 #define for0(i,n) for(int i=0;i<=(n);i++) 20 #define for1(i,n) for(int i=1;i<=(n);i++) 21 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 22 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 23 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next) 24 #define mod 1000000007 25 using namespace std; 26 inline int read() 27 { 28 int x=0,f=1;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 30 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 31 return x*f; 32 } 33 int n,m,rt,cur,ans[10]; 34 struct rec 35 { 36 int d[5],mi[5],mx[5],l,r; 37 int& operator[](int x){return d[x];} 38 }p[maxn],now,t[maxn]; 39 priority_queue<pa>q; 40 bool operator <(rec a,rec b){return a[cur]<b[cur];} 41 inline void pushup(int k) 42 { 43 int l=t[k].l,r=t[k].r; 44 for0(i,m-1) 45 { 46 t[k].mi[i]=min(t[k].mi[i],min(t[l].mi[i],t[r].mi[i])); 47 t[k].mx[i]=max(t[k].mx[i],max(t[l].mx[i],t[r].mx[i])); 48 } 49 } 50 int build(int l,int r,int dir) 51 { 52 int mid=(l+r)>>1; 53 cur=dir; 54 nth_element(p+l,p+mid,p+r+1); 55 t[mid]=p[mid]; 56 for0(i,m-1)t[mid].mx[i]=t[mid].mi[i]=t[mid][i]; 57 t[mid].l=l<mid?build(l,mid-1,(dir+1)%m):0; 58 t[mid].r=mid<r?build(mid+1,r,(dir+1)%m):0; 59 pushup(mid); 60 return mid; 61 } 62 inline int dis(rec a,rec b) 63 { 64 int ret=0; 65 for0(i,m-1)ret+=sqr(a[i]-b[i]); 66 return ret; 67 } 68 inline int calc(int k) 69 { 70 if(!k)return inf; 71 int ret=0; 72 for0(i,m-1)if(now[i]<t[k].mi[i])ret+=sqr(t[k].mi[i]-now[i]); 73 for0(i,m-1)if(now[i]>t[k].mx[i])ret+=sqr(now[i]-t[k].mx[i]); 74 return ret; 75 } 76 void query(int k) 77 { 78 int dl=calc(t[k].l),dr=calc(t[k].r),d0=dis(t[k],now); 79 if(d0<q.top().first){q.pop();q.push(pa(d0,k));} 80 if(dl<dr) 81 { 82 if(dl<q.top().first)query(t[k].l); 83 if(dr<q.top().first)query(t[k].r); 84 }else 85 { 86 if(dr<q.top().first)query(t[k].r); 87 if(dl<q.top().first)query(t[k].l); 88 } 89 } 90 int main() 91 { 92 freopen("input.in","r",stdin); 93 freopen("output.txt","w",stdout); 94 for0(i,4)t[0].mi[i]=inf,t[0].mx[i]=-inf; 95 while(scanf("%d %d",&n,&m)!=EOF) 96 { 97 for1(i,n)for0(j,m-1)p[i][j]=read(); 98 rt=build(1,n,0); 99 int qq=read(); 100 while(qq--) 101 { 102 for0(i,m-1)now[i]=read();n=read(); 103 printf("the closest %d points are:\n",n); 104 for1(i,n)q.push(pa(inf,0)); 105 query(rt); 106 for1(i,n)ans[i]=q.top().second,q.pop(); 107 for3(i,n,1){for0(j,m-1){if(j)printf(" ");printf("%d",t[ans[i]][j]);}printf("\n");} 108 } 109 } 110 return 0; 111 }