您的位置:首页 > 其它

BZOJ3053: The Closest M Points

2014-12-21 10:26 344 查看
题解:

我们可以事先在堆里放入插入m个inf然后不断的比较当前值与堆首元素的大小,如果小于的话进入。

估计函数也可以随便写写。。。

query的时候貌似不用保留dir。。。

return 0写在 while 里面我也是醉了。。。

不用开long long为什么大家都开了。。。

k-d tree助我进第一版

代码:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 2100000000
#define maxn 100000+5
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define sqr(x) (x)*(x)
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
int n,m,rt,cur,ans[10];
struct rec
{
int d[5],mi[5],mx[5],l,r;
int& operator[](int x){return d[x];}
}p[maxn],now,t[maxn];
priority_queue<pa>q;
bool operator <(rec a,rec b){return a[cur]<b[cur];}
inline void pushup(int k)
{
int l=t[k].l,r=t[k].r;
for0(i,m-1)
{
t[k].mi[i]=min(t[k].mi[i],min(t[l].mi[i],t[r].mi[i]));
t[k].mx[i]=max(t[k].mx[i],max(t[l].mx[i],t[r].mx[i]));
}
}
int build(int l,int r,int dir)
{
int mid=(l+r)>>1;
cur=dir;
nth_element(p+l,p+mid,p+r+1);
t[mid]=p[mid];
for0(i,m-1)t[mid].mx[i]=t[mid].mi[i]=t[mid][i];
t[mid].l=l<mid?build(l,mid-1,(dir+1)%m):0;
t[mid].r=mid<r?build(mid+1,r,(dir+1)%m):0;
pushup(mid);
return mid;
}
inline int dis(rec a,rec b)
{
int ret=0;
for0(i,m-1)ret+=sqr(a[i]-b[i]);
return ret;
}
inline int calc(int k)
{
if(!k)return inf;
int ret=0;
for0(i,m-1)if(now[i]<t[k].mi[i])ret+=sqr(t[k].mi[i]-now[i]);
for0(i,m-1)if(now[i]>t[k].mx[i])ret+=sqr(now[i]-t[k].mx[i]);
return ret;
}
void query(int k)
{
int dl=calc(t[k].l),dr=calc(t[k].r),d0=dis(t[k],now);
if(d0<q.top().first){q.pop();q.push(pa(d0,k));}
if(dl<dr)
{
if(dl<q.top().first)query(t[k].l);
if(dr<q.top().first)query(t[k].r);
}else
{
if(dr<q.top().first)query(t[k].r);
if(dl<q.top().first)query(t[k].l);
}
}
int main()
{
freopen("input.in","r",stdin);
freopen("output.txt","w",stdout);
for0(i,4)t[0].mi[i]=inf,t[0].mx[i]=-inf;
while(scanf("%d %d",&n,&m)!=EOF)
{
for1(i,n)for0(j,m-1)p[i][j]=read();
rt=build(1,n,0);
int qq=read();
while(qq--)
{
for0(i,m-1)now[i]=read();n=read();
printf("the closest %d points are:\n",n);
for1(i,n)q.push(pa(inf,0));
query(rt);
for1(i,n)ans[i]=q.top().second,q.pop();
for3(i,n,1){for0(j,m-1){if(j)printf(" ");printf("%d",t[ans[i]][j]);}printf("\n");}
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: