【BZOJ2648】SJY摆棋子

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

题解:初学KDtree,感兴趣的可以看一下

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep for(i=0;i<=1;i++)
using namespace std;
struct KD
{
int ls,rs,v[2],sn[2],sm[2];
KD (int a,int b){ls=rs=0,sn[0]=sm[0]=v[0]=a,sn[1]=sm[1]=v[1]=b;}
KD (){}
}t[1000010];
int D,n,m,tot,ans,root;
bool cmp(KD a,KD b)
{
if(a.v[D]==b.v[D]) return a.v[D^1]<b.v[D^1];
return a.v[D]<b.v[D];
}
void pushup(int x,int y)
{
int i;
rep t[x].sn[i]=min(t[x].sn[i],t[y].sn[i]),t[x].sm[i]=max(t[x].sm[i],t[y].sm[i]);
}
int getdis(int x,int y)
{
int ret=0,i;
rep ret+=max(t[x].sn[i]-t[y].v[i],0)+max(t[y].v[i]-t[x].sm[i],0);
return ret;
}
int build(int l,int r,int d)
{
if(l>r) return 0;
D=d;
int mid=l+r>>1;
nth_element(t+l,t+mid,t+r+1,cmp);
t[mid].ls=build(l,mid-1,d^1);
t[mid].rs=build(mid+1,r,d^1);
if(t[mid].ls) pushup(mid,t[mid].ls);
if(t[mid].rs) pushup(mid,t[mid].rs);
return mid;
}
void insert(int y)
{
int x=root;
D=0;
while(1)
{
pushup(x,y);
if(t[y].v[D]<t[x].v[D])
{
if(t[x].ls) x=t[x].ls;
else {t[x].ls=y,pushup(x,y); break;}
}
else
{
if(t[x].rs) x=t[x].rs;
else {t[x].rs=y,pushup(x,y); break;}
}
D^=1;
}
}
void query(int x,int y)
{
if(!x||getdis(x,y)>ans) return ;
ans=min(ans,abs(t[x].v[0]-t[y].v[0])+abs(t[x].v[1]-t[y].v[1]));
if(!(t[x].ls*t[x].rs))
{
query(t[x].ls^t[x].rs,y);
return ;
}
int dl=getdis(t[x].ls,y),dr=getdis(t[x].rs,y);
if(dl<dr) query(t[x].ls,y),query(t[x].rs,y);
else query(t[x].rs,y),query(t[x].ls,y);
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b,c;
for(i=1;i<=n;i++) a=rd(),b=rd(),t[i]=KD(a,b);
root=build(1,n,0);
for(i=1;i<=m;i++)
{
a=rd(),b=rd(),c=rd(),t[i+n]=KD(b,c);
if(a==1) insert(i+n);
else ans=1<<30,query(root,i+n),printf("%d\n",ans);
}
return 0;
}

最新文章

  1. AssetBundle
  2. windows server 2003(64位)上利用iis6部署32位应用
  3. 第 1 章 Bootstrap 介绍
  4. winform里面网页显示指定内容
  5. EF图解
  6. Differences Between Xcode Project Templates for iOS Apps
  7. Teamwork-Week2真对必应词典和有道词典的软件分析和用户需求调查(桌面版)
  8. UI线程与worker线程
  9. JMS样本
  10. 下载一个应用程序,华硕手机秒变3D扫描仪
  11. es5 中类的2种基本实现方法
  12. 1305 Pairwise Sum and Divide
  13. iOS 友盟错误分析-2019
  14. Selenium Navigation
  15. 洛谷 P1426小鱼会有危险吗
  16. Javascript 对象 - 数组对象
  17. BBS(第二天) Django之Admin 自动化管理数据页面 与创建一个用户注册的验证码
  18. aop 记录用户操作(一)
  19. 【轻松前端之旅】元素,标记,属性,&lt;html&gt;标签
  20. SqlExcel使用文档及源码

热门文章

  1. vue - config
  2. Django——django1.6 基于类的通用视图
  3. 笛卡尔树 POJ ——1785 Binary Search Heap Construction
  4. JavaScript | 基础表单验证(纯Js)
  5. UITabBarController超强拓展
  6. IOS 多播委托(GCDMulticastDelegate)
  7. BEGINNING SHAREPOINT&amp;#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围
  8. html5在移动端的屏幕适应性问题
  9. Atitit.&#160;真正的全中国文字attilax易语言的特点以及范例
  10. CDH配置JAVA_HOME