传送门

kd−treekd-treekd−tree模板题。

题意简述:支持在平面上插入一个点,求对于一个点的最近点对。


思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息

所以我用了kd−treekd-treekd−tree来做。

其实就是两个维度分别作为键值来建立二叉搜索树即可。

这道题在查询时可以通过判断下一层的有没有可能对答案有贡献来剪个枝。

由于蒟蒻暂时没写过方差划分因此时间很慢。

代码:

#include<bits/stdc++.h>
#define mid (l+r>>1)
#define ri register int
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
typedef pair<int,int> pii;
const int N=1e6+5,inf=0x3f3f3f3f;
int n,m,mx[N][2],mn[N][2],son[N][2],ans,tot=0;
bool cmpdir;
struct Pot{
    int a[2];
    inline int&operator[](const int&k){return a[k];}
    inline const int&operator[](const int&k)const{return a[k];}
}p[N];
inline bool cmp(const Pot&a,const Pot&b){return a[cmpdir]<b[cmpdir];}
inline void pushup(int p){
    if(son[p][0]){
        mn[p][0]=min(mn[p][0],mn[son[p][0]][0]);
        mx[p][0]=max(mx[p][0],mx[son[p][0]][0]);
        mn[p][1]=min(mn[p][1],mn[son[p][0]][1]);
        mx[p][1]=max(mx[p][1],mx[son[p][0]][1]);
    }
    if(son[p][1]){
        mn[p][0]=min(mn[p][0],mn[son[p][1]][0]);
        mx[p][0]=max(mx[p][0],mx[son[p][1]][0]);
        mn[p][1]=min(mn[p][1],mn[son[p][1]][1]);
        mx[p][1]=max(mx[p][1],mx[son[p][1]][1]);
    }
}
inline int build(int l,int r,bool d){
    cmpdir=d;
    nth_element(p+l,p+mid,p+r+1,cmp);
    mn[mid][0]=mx[mid][0]=p[mid][0],mn[mid][1]=mx[mid][1]=p[mid][1];
    if(l<mid)son[mid][0]=build(l,mid-1,d^1);
    if(r>mid)son[mid][1]=build(mid+1,r,d^1);
    return pushup(mid),mid;
}
inline void insert(int k,Pot v,bool d){
    if(p[k][d]<=v[d]){
        if(son[k][1])insert(son[k][1],v,d^1);
        else{
            p[son[k][1]=++tot]=v;
            mx[tot][0]=mn[tot][0]=v[0];
            mx[tot][1]=mn[tot][1]=v[1];
        }
    }
    else{
        if(son[k][0])insert(son[k][0],v,d^1);
        else{
            p[son[k][0]=++tot]=v;
            mx[tot][0]=mn[tot][0]=v[0];
            mx[tot][1]=mn[tot][1]=v[1];
        }
    }
    pushup(k);
}
inline int ask(int k,Pot v){
    int ret=0;
    ret+=max(0,mn[k][0]-v[0]);
    ret+=max(0,mn[k][1]-v[1]);
    ret+=max(0,v[0]-mx[k][0]);
    ret+=max(0,v[1]-mx[k][1]);
    return ret;
}
inline int dist(Pot a,Pot b){return abs(a[0]-b[0])+abs(a[1]-b[1]);}
inline void query(int k,Pot v,bool d){
    ans=min(ans,dist(p[k],v));
    int al=inf,ar=inf;
    if(son[k][0])al=ask(son[k][0],v);
    if(son[k][1])ar=ask(son[k][1],v);
    if(al<ar){
        if(al<ans)query(son[k][0],v,d^1);
        if(ar<ans)query(son[k][1],v,d^1);
    }
    else{
        if(ar<ans)query(son[k][1],v,d^1);
        if(al<ans)query(son[k][0],v,d^1);
    }
}
int main(){
    n=read(),m=read(),tot=0;
    for(ri i=1,x,y;i<=n;++i)x=read(),y=read(),p[++tot]=(Pot){x,y};
    for(ri rt=build(1,n,0),i=1,x,y,op;i<=m;++i){
        op=read(),x=read(),y=read();
        if(op==1)insert(rt,(Pot){x,y},0);
        else ans=inf,query(rt,(Pot){x,y},0),cout<<ans<<'\n';
    }
    return 0;
}

2019.01.14 bzoj2648: SJY摆棋子(kd-tree)的更多相关文章

  1. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

  2. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  3. BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶

    BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...

  4. [BZOJ2648] SJY摆棋子 kd-tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 5421  Solved: 1910[Submit][Status][Disc ...

  5. Bzoj2648 SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 3128  Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ...

  6. bzoj 2648 SJY摆棋子 kd树

    题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...

  7. 【kd-tree】bzoj2648 SJY摆棋子

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

  8. BZOJ2648 SJY摆棋子(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  9. [bzoj2648]SJY摆棋子(带插入kd-tree)

    解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ...

随机推荐

  1. if (HttpContext.Current.User.Identity.IsAuthenticated) 权限验证总是true

    将浏览器关闭重启. 注:该语句是判断用户是否经过验证.

  2. JAVA去重

    JAVA中去掉空格 1. String.trim() trim()是去掉首尾空格 2.str.replace(" ", ""); 去掉所有空格,包括首尾.中间 ...

  3. vue项目引入FastClick组件解决IOS系统下h5页面中的按钮点击延迟,连续点击无反应的问题

    异常描述: ios系统手机中访问h5页面,按钮点击有延迟,连续点击卡顿.无反应. 异常原因: 这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设 ...

  4. day 27 Python中进程的操作

    进程的创建和结束: multiprocess模块: multiprocess不是一个模块而是python中一个操作.管理进程的包 分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享 ...

  5. Oracle_SQL(7) 复杂查询

    1.rownum 伪列<,<=select * from emp where rownum<5; 取工资前3名的人员 select * from (select * from emp ...

  6. laravel框架一次请求的生命周期

    第一件事所有的请求都会被web服务器(Apache/Nginx)导向public/index.php文件.index.php文件载入Composer生成的自动加载设置,然后从bootstrap/app ...

  7. JoyOI1391 走廊泼水节

    一道另类生成树 原题链接 将输入的树的\(n-1\)条边按从小到大排序,然后\(Kruskal\)在生成该树的过程中计算新增边的总长. 当在连第\(i\)条边,设该边的两端点为\(x,y\),长度为\ ...

  8. 发送邮件--MFMailComposeViewController

    只能在真机使用. 模拟器没有E-mail发送功能.无法调用 #import "EmailViewController.h" #import <UIKit/UIKit.h> ...

  9. Scrapy框架——CrawlSpider类爬虫案例

    Scrapy--CrawlSpider Scrapy框架中分两类爬虫,Spider类和CrawlSpider类. 此案例采用的是CrawlSpider类实现爬虫. 它是Spider的派生类,Spide ...

  10. 在nodejs里面是用类似配置文件的方法

    1.a.js exports.MYSQLIP = '127.0.0.1'; exports.MYSQLPORT = 1336; 2.b.js const C = require('./config/c ...