zoukankan      html  css  js  c++  java
  • [BZOJ2648]SJY摆棋子

    bzoj

    题意

    平面上有(n)个点,每次往这个平面上加入一个点,或是询问离某个点最近点的距离。
    这里的距离指的是曼哈顿距离。

    sol

    (kd-Tree)了解一下?
    (O(nlog n))建树,然后(O(msqrt n))查询。
    插入导致树的不平衡?
    定期重构即可。

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    #define cmin(a,b) (a>b?a=b:a)
    #define cmax(a,b) (a<b?a=b:a)
    #define ls t[o].ch[0]
    #define rs t[o].ch[1]
    #define inf 2147483647
    const int N = 5e5+5;
    int n,m,root,D,ans;
    struct node{
    	int d[2];
    	bool operator < (const node &b) const
    		{return d[D]<b.d[D];}
    }a[N];
    struct kdtree{int d[2],Min[2],Max[2],ch[2];}t[N<<1];
    void mt(int x,int y)
    {
    	cmin(t[x].Min[0],t[y].Min[0]);cmax(t[x].Max[0],t[y].Max[0]);
    	cmin(t[x].Min[1],t[y].Min[1]);cmax(t[x].Max[1],t[y].Max[1]);
    }
    int build(int l,int r,int d)
    {
    	D=d;int o=l+r>>1;
    	nth_element(a+l,a+o,a+r+1);
    	t[o].d[0]=t[o].Min[0]=t[o].Max[0]=a[o].d[0];
    	t[o].d[1]=t[o].Min[1]=t[o].Max[1]=a[o].d[1];
    	if (l<o) ls=build(l,o-1,d^1),mt(o,ls);
    	if (o<r) rs=build(o+1,r,d^1),mt(o,rs);
    	return o;
    }
    int dist(int o,int x,int y)
    {
    	return max(t[o].Min[0]-x,0)+max(x-t[o].Max[0],0)+max(t[o].Min[1]-y,0)+max(y-t[o].Max[1],0);
    }
    void query(int o,int x,int y)
    {
    	int tmp=abs(t[o].d[0]-x)+abs(t[o].d[1]-y),d[2];
    	if (ls) d[0]=dist(ls,x,y);else d[0]=inf;
    	if (rs) d[1]=dist(rs,x,y);else d[1]=inf;
    	cmin(ans,tmp);tmp=d[0]>=d[1];
    	if (d[tmp]<ans) query(t[o].ch[tmp],x,y);tmp^=1;
    	if (d[tmp]<ans) query(t[o].ch[tmp],x,y);
    }
    int main()
    {
    	n=gi();m=gi();
    	for (int i=1;i<=n;++i) a[i].d[0]=gi(),a[i].d[1]=gi();
    	root=build(1,n,0);
    	while (m--){
    		int op=gi(),x=gi(),y=gi();
    		if (op==1){
    			++n;
    			t[n].d[0]=t[n].Min[0]=t[n].Max[0]=x;
    			t[n].d[1]=t[n].Min[1]=t[n].Max[1]=y;
    			for (int p=root,d=0;p;d^=1)
    			{
    				mt(p,n);
    				int &nxt=t[p].ch[t[n].d[d]>=t[p].d[d]];
    				if (!nxt) {nxt=n;break;}p=nxt;
    			}
    		}
    		else{
    			ans=inf;query(root,x,y);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Kubernetes Jenkins动态创建Slave
    运维故障汇总
    Spinnaker调用Jenkins API 返回403错误
    linux删除文件空间不释放问题解决
    华为 路由交换之DHCP
    华为 路由交换之PPPoE
    关于==和equals的探索
    springboot&mybatis 增删改查系列(二)
    springboot&mybatis 增删改查系列(一)
    nginx简单使用(windows)
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8945805.html
Copyright © 2011-2022 走看看