K-D Tree 求助神奇错误
查看原帖
K-D Tree 求助神奇错误
376997
Harry27182SDream楼主2022/2/2 10:36

第三个测试点显示Wrong Answer.wrong answer On line 3 column 1, read 6, expected 5.,然后调了一会调不出来,下载数据本地测试输出是 5,怀疑是本地和洛谷不同导致,然后重构数据用洛谷 IDE 测试,结果也是 5,求助 WA/kel

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define alpha 0.9
using namespace std;
struct node
{
	int x,y,ls,rs,l[2],r[2],size,d;
}e[600005];
int g[600005],n,m,root,tot,op,qx,qy,t,ans;
int read()
{ 
	int f=1,x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	return x*f;
}
bool cmpx(int a,int b)
{
	return e[a].x<e[b].x;
}
bool cmpy(int a,int b)
{
	return e[a].y<e[b].y;
}
void maintain(int x)
{
	e[x].size=e[e[x].ls].size+e[e[x].rs].size+1;
	e[x].l[0]=e[x].r[0]=e[x].x;
	e[x].l[1]=e[x].r[1]=e[x].y;
	if(e[x].ls)
	{
		e[x].l[0]=min(e[x].l[0],e[e[x].ls].l[0]);
		e[x].l[1]=min(e[x].l[1],e[e[x].ls].l[1]);
		e[x].r[0]=max(e[x].r[0],e[e[x].ls].r[0]);
		e[x].r[1]=max(e[x].r[1],e[e[x].rs].r[1]);
	}
	if(e[x].rs)
	{
		e[x].l[0]=min(e[x].l[0],e[e[x].rs].l[0]);
		e[x].l[1]=min(e[x].l[1],e[e[x].rs].l[1]);
		e[x].r[0]=max(e[x].r[0],e[e[x].rs].r[0]);
		e[x].r[1]=max(e[x].r[1],e[e[x].rs].r[1]);
	}
}
int build(int l,int r)
{
	if(l>r)return 0;
	int mid=(l+r)>>1;
	double av[2],va[2];
	av[0]=av[1]=va[0]=va[1]=0.0;
	for(int i=l;i<=r;i++)
	{
		av[0]+=(double)e[g[i]].x;
		av[1]+=(double)e[g[i]].y;
	} 
	av[0]/=(double)(r-l+1);av[1]/=(double)(r-l+1);
	for(int i=l;i<=r;i++)
	{
		va[0]+=(av[0]-(double)e[g[i]].x)*(av[0]-(double)e[g[i]].x);
		va[1]+=(av[1]-(double)e[g[i]].y)*(av[1]-(double)e[g[i]].y);
	}
	if(va[0]>va[1])
	{
		nth_element(g+l,g+mid,g+r+1,cmpx);
		e[g[mid]].d=1;
	}
	else
	{
		nth_element(g+l,g+mid,g+r+1,cmpy);
		e[g[mid]].d=2;
	}
	e[g[mid]].ls=build(l,mid-1);
	e[g[mid]].rs=build(mid+1,r);
	maintain(g[mid]);
	return g[mid];
}
void getson(int x)
{
	if(!x)return;
	getson(e[x].ls);
	g[++t]=x;
	getson(e[x].rs);
}
void rebuild(int &x)
{
	t=0;
	getson(x);
	x=build(1,t);
}
bool bad(int x)
{
	return alpha*(double)e[x].size<=(double)max(e[e[x].ls].size,e[e[x].rs].size);
}
void insert(int &x,int k)
{
	if(!x)
	{
		x=k;
		maintain(k);
		return;
	}
	if(e[x].d==1)
	{
		if(e[k].x<=e[x].x)insert(e[x].ls,k);
		else insert(e[x].rs,k);
	}
	else
	{
		if(e[k].y<=e[x].y)insert(e[x].ls,k);
		else insert(e[x].rs,k);
	}
	maintain(x);
	if(bad(x))rebuild(x);
}
int getdis(int x,int qx,int qy)
{
	return max(0,qx-e[x].r[0])+max(0,e[x].l[0]-qx)+max(0,qy-e[x].r[1])+max(0,e[x].l[1]-qy);
}
int dis(int x,int qx,int qy)
{
	return abs(qx-e[x].x)+abs(qy-e[x].y);
}
void query(int x)
{
	ans=min(ans,dis(x,qx,qy));
	int dl=inf,dr=inf;
	if(e[x].ls)dl=getdis(e[x].ls,qx,qy);
	if(e[x].rs)dr=getdis(e[x].rs,qx,qy);
	if(dl<dr)
	{
		if(dl<ans)query(e[x].ls);
		if(dr<ans)query(e[x].rs);
	}
	else
	{
		if(dr<ans)query(e[x].rs);
		if(dl<ans)query(e[x].ls);
	}
}
int main()
{
	n=read();m=read();
	for(int i=1;i<=n;i++)
	{
		e[i].x=read();e[i].y=read();
		g[i]=i;
	}
	tot=n;
	root=build(1,tot);
	for(int i=1;i<=m;i++)
	{
		op=read();
		if(op==1)
		{
			tot++;
			e[tot].x=read();e[tot].y=read();
			insert(root,tot);
		}
		else
		{
			qx=read();qy=read();
			ans=inf;
			query(root);
			printf("%d\n",ans);
		}
	}
	return 0;
}
2022/2/2 10:36
加载中...