【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4605

【题目大意】

  操作 1 x y k 表示在点(x,y)上放置k个物品,
  操作 2 x0 y0 x1 y1 k 表示查询矩形内放置物品第k多的格子有几个物品
  同一个格子不会被同时放置物品一次以上

【题解】

  内层用替罪羊式的KD树动态维护加点,和查询矩形内点数
  外层用权值线段树维护KD树的权值编号
  对于每个权值点,添加到权值线段树查询路径上的每一颗KD树上,
  这样就保证了区间的二进制拆分区间总可以被查询到

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=3000000,INF=1e9;
namespace KD_Tree{
struct Dot{
int d[2],mn[2],mx[2],l,r,sz;
Dot(){l=r=0;}
Dot(int x,int y){d[0]=x;d[1]=y;l=r=0;}
int& operator [] (int x){return d[x];}
};
int D,dcnt=0;
Dot T[N];
inline void umax(int&a,int b){if(a<b)a=b;}
inline void umin(int&a,int b){if(a>b)a=b;}
inline bool cmp(int x,int y){return T[x][D]<T[y][D];}
inline void up(int x){
T[x].sz=T[T[x].l].sz+T[T[x].r].sz+1;
T[x].mn[0]=T[x].mx[0]=T[x][0];
T[x].mn[1]=T[x].mx[1]=T[x][1];
if(T[x].l){
umax(T[x].mx[0],T[T[x].l].mx[0]);
umin(T[x].mn[0],T[T[x].l].mn[0]);
umax(T[x].mx[1],T[T[x].l].mx[1]);
umin(T[x].mn[1],T[T[x].l].mn[1]);
}
if(T[x].r){
umax(T[x].mx[0],T[T[x].r].mx[0]);
umin(T[x].mn[0],T[T[x].r].mn[0]);
umax(T[x].mx[1],T[T[x].r].mx[1]);
umin(T[x].mn[1],T[T[x].r].mn[1]);
}
}
inline int NewDot(int x,int y){
++dcnt;
T[dcnt][0]=x; T[dcnt][1]=y;
return up(dcnt),dcnt;
}
int query(int x,int x0,int y0,int x1,int y1){
if(!x||T[x].mn[0]>x1||T[x].mx[0]<x0||T[x].mn[1]>y1||T[x].mx[1]<y0)return 0;
if(T[x].mn[0]>=x0&&T[x].mx[0]<=x1&&T[x].mn[1]>=y0&&T[x].mx[1]<=y1)return T[x].sz;
int res=0;
if(T[x][0]>=x0&&T[x][0]<=x1&&T[x][1]>=y0&&T[x][1]<=y1)res++;
return res+query(T[x].l,x0,y0,x1,y1)+query(T[x].r,x0,y0,x1,y1);
}
int tot=0,pt[N];
int gt,gtd,gtf;
const double alp=0.8;
inline bool isbad(int x){
return max(T[T[x].l].sz,T[T[x].r].sz)>T[x].sz*alp+5;
}
void ins(int&x,int D,const Dot&p){
if(!x){x=NewDot(p.d[0],p.d[1]);return;}
if(p.d[D]<T[x][D])ins(T[x].l,D^1,p);
else ins(T[x].r,D^1,p);
up(x);
if(isbad(x))gt=x,gtd=D,gtf=0;
else if(gt==T[x].l||gt==T[x].r)gtf=x;
}
void treavel(int&x){
if(!x)return;
pt[++tot]=x;
treavel(T[x].l),treavel(T[x].r);
}
int build(int l,int r,int now){
if(l>r)return 0;
int mid=(l+r)>>1,x;
D=now;
nth_element(pt+l,pt+mid,pt+r+1,cmp);
x=pt[mid];
T[x].l=build(l,mid-1,now^1);
T[x].r=build(mid+1,r,now^1);
return up(x),x;
}
void Insert(int&x,const Dot&p){
gt=gtf=0,ins(x,0,p);
if(!gt)return;
tot=0,treavel(gt);
if(!gtf){x=build(1,tot,gtd);return;}
if(gt==T[gtf].l)T[gtf].l=build(1,tot,gtd);
else T[gtf].r=build(1,tot,gtd);
}
}
int tot=0;
struct data{int rt,l,r;}T[N];
void Insert(int &x,const KD_Tree::Dot&p,int val,int l=1,int r=INF){
if(!x)x=++tot;
KD_Tree::Insert(T[x].rt,p);
if(l==r)return;
int mid=(l+r)>>1;
if(val<=mid)Insert(T[x].l,p,val,l,mid);
else Insert(T[x].r,p,val,mid+1,r);
}
int query(int x,int x0,int y0,int x1,int y1,int k,int l=1,int r=INF){
if(l==r)return l;
int rcnt=KD_Tree::query(T[T[x].r].rt,x0,y0,x1,y1);
int mid=(l+r)>>1;
if(k<=rcnt)return query(T[x].r,x0,y0,x1,y1,k,mid+1,r);
return query(T[x].l,x0,y0,x1,y1,k-rcnt,l,mid);
}
int n,q,op,x0,y0,x1,y1,k,root=0,ans=0;
int main(){
scanf("%d%d",&n,&q);
while(q--){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x0,&y0,&k);
x0^=ans,y0^=ans,k^=ans;
KD_Tree::Dot p=KD_Tree::Dot(x0,y0);
Insert(root,p,k);
}else{
scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&k);
x0^=ans,y0^=ans,x1^=ans,y1^=ans,k^=ans;
int res=KD_Tree::query(T[root].rt,x0,y0,x1,y1);
if(res<k)puts("NAIVE!ORZzyz."),ans=0;
else printf("%d\n",ans=query(root,x0,y0,x1,y1,k));
}
}return 0;
}

BZOJ 4605 崂山白花蛇草水(权值线段树+KD树)的更多相关文章

  1. bzoj4605: 崂山白花蛇草水 权值线段树套KDtree

    bzoj4605: 崂山白花蛇草水 链接 bzoj loj 思路 强制在线,那就权值线段树套KDtree好了,没啥好讲的. KDtree要加平衡因子来重构.另外,那水真难喝. 错误 树套树一边写过了, ...

  2. 【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree

    [BZOJ4605]崂山白花蛇草水 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了 ...

  3. 【bzoj4605】崂山白花蛇草水 权值线段树套KD-tree

    题目描述 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了.蒟蒻Bob ...

  4. 崂山白花蛇草水 权值线段树套KDtree

    Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...

  5. 洛谷P4848 崂山白花蛇草水 权值线段树+KDtree

    题目描述 神犇 \(Aleph\) 在 \(SDOI\ Round2\) 前立了一个 \(flag\):如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇 \(Aleph\) 的实力,他轻松地进了山 ...

  6. bzoj 4605: 崂山白花蛇草水

    Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...

  7. bzoj 4627: [BeiJing2016]回转寿司 -- 权值线段树

    4627: [BeiJing2016]回转寿司 Time Limit: 10 Sec  Memory Limit: 256 MB Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店. ...

  8. bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】

    bzoj上数组开大会T-- 本来想用set瞎搞的,想了想发现不行 总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪 ...

  9. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

随机推荐

  1. 【Python项目】简单爬虫批量获取资源网站的下载链接

    简单爬虫批量获取资源网站的下载链接 项目链接:https://github.com/RealIvyWong/GotDownloadURL 1 由来 自己在收集剧集资源的时候,这些网站的下载链接还要手动 ...

  2. C 之回调函数

    软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用.同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用:回调是一种双向调用模式,也就是 ...

  3. 使用数据库管理工具打开MySql

    1.推荐使用软件:Navicat_Premium_11.0.10.exe.  下载地址:http://pan.baidu.com/s/1nu6mTF7 2.下载上面文件并安装. 3.打开Navicat ...

  4. Jenkins忘记用户名密码

    一.进入C盘.jenkins配置文件中找到config.xml 需要删除一下内容: <useSecurity>true</useSecurity> <authorizat ...

  5. 27 Debugging Go Code with GDB 使用GDB调试go代码

    Debugging Go Code with GDB  使用GDB调试go代码 Introduction Common Operations Go Extensions Known Issues Tu ...

  6. elasticsearch文档学习

    1.集群 节点(一个elasticsearch实体)  索引  主节点 :集群级别变更,新增或移除节点,索引:  主节点不参与文档级别搜索和变更. 分片(shard):一个完整的搜索引擎,lucene ...

  7. SSIS 学习之旅 FTP访问类

    这章把脚本任务访问FTP的方法 全部给大家. 控件的使用大家如果有不懂得可以看下我之前的文章.第一章:SSIS 学习之旅 第一个SSIS 示例(一)(上) 第二章:SSIS 学习之旅 第一个SSIS ...

  8. 《HBase实战》学习笔记

    第二章  入门 HBase写路径: 增加新行和修改已有的行,内部机制是一样的. 写入的时候,会写到预写日志(WAL)和MemStore中. MenmStore是内存里的写入缓冲区.填满后,会将数据刷写 ...

  9. day6 subprocess模块、logging模块

        logging模块 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储 ...

  10. bzoj 1264 [AHOI2006]基因匹配Match dp + 树状数组

    思路:好难想啊, 考虑到应该从每个数字只有5个数字下手, 但是不知道到底该怎么写.. 首先我们将第一个串按数字的种类分类, 每一类里面有5个, 然后将第二个串里面的数字一个一个加,如果一个加入的第 i ...