BZOJ 4605 崂山白花蛇草水(权值线段树+KD树)
【题目链接】 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树)的更多相关文章
- bzoj4605: 崂山白花蛇草水 权值线段树套KDtree
bzoj4605: 崂山白花蛇草水 链接 bzoj loj 思路 强制在线,那就权值线段树套KDtree好了,没啥好讲的. KDtree要加平衡因子来重构.另外,那水真难喝. 错误 树套树一边写过了, ...
- 【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree
[BZOJ4605]崂山白花蛇草水 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了 ...
- 【bzoj4605】崂山白花蛇草水 权值线段树套KD-tree
题目描述 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了.蒟蒻Bob ...
- 崂山白花蛇草水 权值线段树套KDtree
Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...
- 洛谷P4848 崂山白花蛇草水 权值线段树+KDtree
题目描述 神犇 \(Aleph\) 在 \(SDOI\ Round2\) 前立了一个 \(flag\):如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇 \(Aleph\) 的实力,他轻松地进了山 ...
- bzoj 4605: 崂山白花蛇草水
Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...
- bzoj 4627: [BeiJing2016]回转寿司 -- 权值线段树
4627: [BeiJing2016]回转寿司 Time Limit: 10 Sec Memory Limit: 256 MB Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店. ...
- bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】
bzoj上数组开大会T-- 本来想用set瞎搞的,想了想发现不行 总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪 ...
- [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)
[BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
随机推荐
- 【Python项目】简单爬虫批量获取资源网站的下载链接
简单爬虫批量获取资源网站的下载链接 项目链接:https://github.com/RealIvyWong/GotDownloadURL 1 由来 自己在收集剧集资源的时候,这些网站的下载链接还要手动 ...
- C 之回调函数
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用.同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用:回调是一种双向调用模式,也就是 ...
- 使用数据库管理工具打开MySql
1.推荐使用软件:Navicat_Premium_11.0.10.exe. 下载地址:http://pan.baidu.com/s/1nu6mTF7 2.下载上面文件并安装. 3.打开Navicat ...
- Jenkins忘记用户名密码
一.进入C盘.jenkins配置文件中找到config.xml 需要删除一下内容: <useSecurity>true</useSecurity> <authorizat ...
- 27 Debugging Go Code with GDB 使用GDB调试go代码
Debugging Go Code with GDB 使用GDB调试go代码 Introduction Common Operations Go Extensions Known Issues Tu ...
- elasticsearch文档学习
1.集群 节点(一个elasticsearch实体) 索引 主节点 :集群级别变更,新增或移除节点,索引: 主节点不参与文档级别搜索和变更. 分片(shard):一个完整的搜索引擎,lucene ...
- SSIS 学习之旅 FTP访问类
这章把脚本任务访问FTP的方法 全部给大家. 控件的使用大家如果有不懂得可以看下我之前的文章.第一章:SSIS 学习之旅 第一个SSIS 示例(一)(上) 第二章:SSIS 学习之旅 第一个SSIS ...
- 《HBase实战》学习笔记
第二章 入门 HBase写路径: 增加新行和修改已有的行,内部机制是一样的. 写入的时候,会写到预写日志(WAL)和MemStore中. MenmStore是内存里的写入缓冲区.填满后,会将数据刷写 ...
- day6 subprocess模块、logging模块
logging模块 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储 ...
- bzoj 1264 [AHOI2006]基因匹配Match dp + 树状数组
思路:好难想啊, 考虑到应该从每个数字只有5个数字下手, 但是不知道到底该怎么写.. 首先我们将第一个串按数字的种类分类, 每一类里面有5个, 然后将第二个串里面的数字一个一个加,如果一个加入的第 i ...