BZOJ2648: SJY摆棋子

BZOJ2716: [Violet 3]天使玩偶

BZOJ氪金无极限。。。

其实这两道是同一题。

附上2648的题面:

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

题解Here!

没有插入操作,就无脑$K-D\ Tree$即可。
有了插入操作怎么办呢?
我们可以类比于平衡树,查找要插入的点应该在什么位置。
然后插入就好。
但是很容易就会发现这玩意会形成一条链。
复杂度笋干爆炸。。。
怎么办呢?
$K-D\ Tree$一大缺点就是建好的树不能再动。
暴力重建?
复杂度依然$GG$。。。
等一下!不能每次都暴力重建,那我就偶尔几次暴力重建就是了?
对,这种方法已经被成功运用到替罪羊树中。
设$\alpha=0.75$,当前在$x$处。
假如$x$的左右子树中有一颗子树的大小$>x\text{的子树大小}\times\alpha$,说明该子树已经极其不平衡。
我们需要对其进行暴力拍平重建。
拍平代码的话,大概长这个样子:
void pia(int rt,int num){
if(a[rt].lson)pia(a[rt].lson,num);
point[num+a[a[rt].lson].size+1]=a[rt].point;
recycle[++top]=rt;
if(a[rt].rson)pia(a[rt].rson,num+a[a[rt].lson].size+1);
}
重建的话,和最开始的建树过程相同。
这样,插入操作就解决了。
期望复杂度$O(\text{能过})$。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define MAXN 1000010
#define MAX (1LL<<30)
#define Alpha 0.75
using namespace std;
int n,m,root,ans,size=0;
int top=0,recycle[MAXN];
bool sort_flag=false;
struct Point{
int x,y;
friend bool operator <(const Point &p,const Point &q){
if(sort_flag)return p.y<q.y;
return p.x<q.x;
}
}point[MAXN],now;
struct Tree{
Point point;
int minx,miny,maxx,maxy,lson,rson,size;
}a[MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline int get_dis(const Point &p,const Point &q){
return abs(p.x-q.x)+abs(p.y-q.y);
}
inline int newnode(const Point &p){
int rt;
if(top)rt=recycle[top--];
else rt=++size;
a[rt].point=p;
a[rt].maxx=a[rt].minx=p.x;
a[rt].maxy=a[rt].miny=p.y;
a[rt].lson=a[rt].rson=0;
a[rt].size=1;
return rt;
}
inline void pushup(int rt){
int lson=a[rt].lson,rson=a[rt].rson;
a[rt].size=a[lson].size+a[rson].size+1;
a[rt].maxx=max(a[rt].maxx,max(a[lson].maxx,a[rson].maxx));
a[rt].maxy=max(a[rt].maxy,max(a[lson].maxy,a[rson].maxy));
a[rt].minx=min(a[rt].minx,min(a[lson].minx,a[rson].minx));
a[rt].miny=min(a[rt].miny,min(a[lson].miny,a[rson].miny));
}
void buildtree(int l,int r,int &rt,int flag){
int mid=l+r>>1;
sort_flag=flag;
nth_element(point+l,point+mid,point+r+1);
rt=newnode(point[mid]);
if(l<mid)buildtree(l,mid-1,a[rt].lson,flag^1);
if(mid<r)buildtree(mid+1,r,a[rt].rson,flag^1);
pushup(rt);
}
void pia(int rt,int num){
if(a[rt].lson)pia(a[rt].lson,num);
point[num+a[a[rt].lson].size+1]=a[rt].point;
recycle[++top]=rt;
if(a[rt].rson)pia(a[rt].rson,num+a[a[rt].lson].size+1);
}
void check(int &rt,int flag){
if(Alpha*a[rt].size<max(a[a[rt].lson].size,a[a[rt].rson].size)){
pia(rt,0);
buildtree(1,a[rt].size,rt,flag);
}
}
void insert(int &rt,int flag){
if(!rt){
rt=newnode(now);
return;
}
sort_flag=flag;
if(a[rt].point<now)insert(a[rt].rson,flag^1);
else insert(a[rt].lson,flag^1);
pushup(rt);
check(rt,flag);
}
inline int max_dis(int rt){
int x,y;
x=max(now.x-a[rt].maxx,0)+max(a[rt].minx-now.x,0);
y=max(now.y-a[rt].maxy,0)+max(a[rt].miny-now.y,0);
return x+y;
}
void query(int rt){
int dis=get_dis(a[rt].point,now),ldis=MAX,rdis=MAX;
ans=min(ans,dis);
if(a[rt].lson)ldis=max_dis(a[rt].lson);
if(a[rt].rson)rdis=max_dis(a[rt].rson);
if(ldis<rdis){
if(ldis<ans)query(a[rt].lson);
if(rdis<ans)query(a[rt].rson);
}
else{
if(rdis<ans)query(a[rt].rson);
if(ldis<ans)query(a[rt].lson);
}
}
void work(){
int f;
while(m--){
f=read();now.x=read();now.y=read();
if(f==1)insert(root,0);
else{
ans=MAX;
query(root);
printf("%d\n",ans);
}
}
}
void init(){
n=read();m=read();
a[0].maxx=a[0].maxy=-MAX;
a[0].minx=a[0].miny=MAX;
for(int i=1;i<=n;i++){point[i].x=read();point[i].y=read();}
buildtree(1,n,root,0);
}
int main(){
init();
work();
return 0;
}

BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶的更多相关文章

  1. bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree

    2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec  Memory Limit: 128 MB Description 这天,S ...

  2. 【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2716 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  3. bzoj2648SJY摆棋子&&bzoj2716[Violet 3]天使玩偶*

    bzoj2648SJY摆棋子 bzoj2716[Violet 3]天使玩偶 题意: 棋盘上有n个棋子,现在有m个操作,一种是加棋子,一种是查询离某个点最近的棋子.n,m≤500000. 题解: 先将已 ...

  4. BZOJ 2716: [Violet 3]天使玩偶

    2716: [Violet 3]天使玩偶 Time Limit: 80 Sec  Memory Limit: 128 MBSubmit: 1473  Solved: 621[Submit][Statu ...

  5. BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )

    先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...

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

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

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

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

  8. Bzoj2648 SJY摆棋子

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

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

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

随机推荐

  1. python学习之strip()

    定义: Python strip() 方法用于移除字符串头尾指定的字符(默认为空格). 语法: str.strip([chars]); 返回值: 返回移除字符串头尾指定的字符生成的新字符串. 例子: ...

  2. ECMall2.x模板制作入门系列之2(模板标签/语法)

    ECMall2.x模板制作入门系列之2(模板标签/语法) 今天给大家带来一个模板语法的教程.希望能为ECMall模板制作者提供一份参考资料.如有问题.建议和意见,欢迎提出. 在ECMall模板中,用& ...

  3. lua的时间和日期函数

    lua的时间和日期函数 -- ::| 分类: Lua | 标签:lua 时间 函数 |举报|字号 订阅 下载LOFTER客户端 --获取当前的时间戳,单位是秒. time=os.time(); pri ...

  4. CentOS上扩充lv-root空间步骤详解

    查看服务器发现vg_host01-lv_root下的空间占用的比较多,需要扩容. 有以下两种方案: )利用空余的磁盘,扩展lv_root的大小(推荐) )将lv_home的空间挪出一部分给lv_roo ...

  5. Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' 解决方法

    1. 代码 SHOW VARIABLES LIKE 'character_set_%'; 查看一下 显示 +--------------------------+------------------- ...

  6. c# 遇到的问题,求解?

    c# cannot evaluate expression because the code of the current method is optimized.

  7. dbutils使用---QueryRunner实现in批量查询

    sql.append("AND a.").append(MchStore.STORE_PROVINCE_COL).append(" IN ("); for (i ...

  8. android studio 中配置androidAnnotation 的新版正确配置

    apply ].processResources.manifestFile resourcePackageName 'com.peiandsky.firstandroidstudio' }}

  9. [复习] JAVA 遍历目录 (递归调用和非递归)

    JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...

  10. 【转】python处理csv数据

    http://desert3.iteye.com/blog/772246 import csv #从文件读取 reader = csv.reader(file(srcFilePath,'rb')) f ...