zoukankan      html  css  js  c++  java
  • bzoj2648 SJY摆棋子

    2648: SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1821  Solved: 591
    [Submit][Status][Discuss]

    Description

    这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子。假设是白色棋子,他会找出距离这个白色棋子近期的黑色棋子。

    此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。

    如今给出N<=500000个初始棋子。和M<=500000个操作。对于每一个白色棋子。输出距离这个白色棋子近期的黑色棋子的距离。同一个格子可能有多个棋子。

     

    Input

    第一行两个数 N M 
    以后M行,每行3个数 t x y
    假设t=1 那么放下一个黑色棋子
    假设t=2 那么放下一个白色棋子

    Output

    对于每一个T=2 输出一个最小距离
     

    Sample Input

    2 3
    1 1
    2 3
    2 1 2
    1 3 3
    2 4 2

    Sample Output


    1
    2

    HINT

     

    kdtree能够过

    Source




    K-D Tree第一题。唉,人生若仅仅如初见......

    这道题考察的是K-D Tree在近期邻搜索方面的应用。非常显然,对于黑棋。增加到K-D Tree里。对于白棋,询问近期邻。

    以下写一些自己关于这道题的理解吧:

      1.K-D Tree本质上是一种DFS的剪枝优化。

      2.每一层相应的区分维度是循环的。

    因为这道题仅仅有两维,所以能够利用位运算的异或操作。

      3.在每一层的DFS中。有一个get函数,相当于预计了子区域距离那个点近期是多少,注意是预计。下一次的DFS就从dl和dr中较小的一边開始。感觉方法还是非常巧妙的。




    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #define F(i,j,n) for(int i=j;i<=n;i++)
    #define D(i,j,n) for(int i=j;i>=n;i--)
    #define ll long long
    #define maxn 500005
    #define inf 1000000000
    using namespace std;
    int n,m,root,D,ans;
    struct data
    {
    	int d[2],mn[2],mx[2],l,r;
    }p[maxn],t[maxn*2],tmp;
    bool operator<(data a,data b)
    {
    	return a.d[D]<b.d[D];
    }
    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=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    inline int dis(data a,data b)
    {
    	return abs(a.d[0]-b.d[0])+abs(a.d[1]-b.d[1]);
    }
    inline void pushup(int k)
    {
    	int ls=t[k].l,rs=t[k].r;
    	F(i,0,1)
    	{
    		if (ls)
    		{
    			t[k].mn[i]=min(t[k].mn[i],t[ls].mn[i]);
    			t[k].mx[i]=max(t[k].mx[i],t[ls].mx[i]);
    		}
    		if (rs)
    		{
    			t[k].mn[i]=min(t[k].mn[i],t[rs].mn[i]);
    			t[k].mx[i]=max(t[k].mx[i],t[rs].mx[i]);
    		}
    	}
    }
    inline int build(int l,int r,int now)
    {
    	D=now;
    	int mid=(l+r)>>1;
    	nth_element(p+l,p+mid,p+r+1);
    	t[mid]=p[mid];
    	F(i,0,1) t[mid].mn[i]=t[mid].mx[i]=t[mid].d[i];
    	if (l<mid) t[mid].l=build(l,mid-1,now^1);
    	if (mid<r) t[mid].r=build(mid+1,r,now^1);
    	pushup(mid);
    	return mid;
    }
    inline int get(int k,data x)
    {
    	int tmp=0;
    	F(i,0,1) tmp+=max(0,t[k].mn[i]-x.d[i]);
    	F(i,0,1) tmp+=max(0,x.d[i]-t[k].mx[i]);
    	return tmp;
    }
    inline void insert(int k,int now)
    {
    	if (tmp.d[now]>=t[k].d[now])
    	{
    		if (t[k].r) insert(t[k].r,now^1);
    		else
    		{
    			t[k].r=++n;t[n]=tmp;
    			F(i,0,1) t[n].mn[i]=t[n].mx[i]=t[n].d[i];
    		}
    	}
    	else
    	{
    		if (t[k].l) insert(t[k].l,now^1);
    		else
    		{
    			t[k].l=++n;t[n]=tmp;
    			F(i,0,1) t[n].mn[i]=t[n].mx[i]=t[n].d[i];
    		}
    	}
    	pushup(k);
    }
    inline void query(int k,int now)
    {
    	int d,dl=inf,dr=inf;
    	d=dis(t[k],tmp);
    	ans=min(ans,d);
    	if (t[k].l) dl=get(t[k].l,tmp);
    	if (t[k].r) dr=get(t[k].r,tmp);
    	if (dl<dr)
    	{
    		if (dl<ans) query(t[k].l,now^1);
    		if (dr<ans) query(t[k].r,now^1);
    	}
    	else
    	{
    		if (dr<ans) query(t[k].r,now^1);
    		if (dl<ans) query(t[k].l,now^1);
    	}
    }
    int main()
    {
    	n=read();m=read();
    	F(i,1,n){p[i].l=p[i].r=0;p[i].d[0]=read();p[i].d[1]=read();}
    	root=build(1,n,0);
    	tmp.l=tmp.r=0;
    	while (m--)
    	{
    		int opt=read();tmp.d[0]=read();tmp.d[1]=read();
    		if (opt==1) insert(root,0);
    		else
    		{
    			ans=inf;
    			query(root,0);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    


  • 相关阅读:
    网络编程之即时通信程序(聊天室)(一)通信流程简介及通信协议定制
    C#常用加密方法解析
    ASP.NET常用数据绑定控件优劣总结
    使用XPO开发时可以参考使用的架构
    渠道会上的体会
    如何利用第三方SDK开发MSN机器人以及实现语音视频?
    对 XPO 的一些问题的解答
    c++ 参数传递 之引用形参 GIS
    指针与引用的区别 GIS
    c++ const 修饰数组 GIS
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7063001.html
Copyright © 2011-2022 走看看