浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html

题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=4605

在写此题之余,我在某东上买了一箱\(24\)瓶装的崂山白花蛇草水,喝完就再续,准备一直喝到省选结束\(emm\)。

这题用权值线段树套\(kd\) \(tree\)即可轻松解决。不过需要用到类似于替罪羊树的重建。

另外可以加一个小优化,那就是只给线段树的右儿子建\(kd\) \(tree\),因为对\(kd\) \(tree\)进行访问也只会发生在右儿子上。

时间复杂度:\(O(nlognlog10^9+nlog10^9\sqrt{n})\)

空间复杂度:\(O(nlogn+nlog10^9)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
#define bo11 (X2<p[u].mn[0]||p[u].mx[0]<X1)
#define bo12 (Y2<p[u].mn[1]||p[u].mx[1]<Y1)
#define bo21 (X1<=p[u].mn[0]&&p[u].mx[0]<=X2)
#define bo22 (Y1<=p[u].mn[1]&&p[u].mx[1]<=Y2)
#define bo31 (X1<=p[u].c[0]&&p[u].c[0]<=X2)
#define bo32 (Y1<=p[u].c[1]&&p[u].c[1]<=Y2) const double alpha=0.75;
const int maxn=1e5+5,inf=2e9; int n,m,ans,k,X1,Y1,X2,Y2,cnt,pps; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct kd_tree {
int tot,top;
int id[maxn]; struct point {
int ls,rs,siz;
int c[2],mn[2],mx[2]; bool operator<(const point &a)const {
return c[pps]<a.c[pps];
}
}p[maxn*20],tmp[maxn]; void update(int u) {
int ls=p[u].ls,rs=p[u].rs;
p[u].siz=p[ls].siz+1+p[rs].siz;
for(int i=0;i<2;i++) {
int mn=min(p[ls].mn[i],p[rs].mn[i]);
p[u].mn[i]=min(p[u].c[i],mn);
int mx=max(p[ls].mx[i],p[rs].mx[i]);
p[u].mx[i]=max(p[u].c[i],mx);
}
} void ins(int &u,int d) {
if(!u) {
u=++tot;
p[u].c[0]=p[u].mn[0]=p[u].mx[0]=X1;
p[u].c[1]=p[u].mn[1]=p[u].mx[1]=Y1;
p[u].siz=1,p[u].ls=p[u].rs=0;return;
}
int num=d?Y1:X1;
if(num<p[u].c[d])ins(p[u].ls,d^1);
else ins(p[u].rs,d^1);
update(u);
} int rebuild(int l,int r,int d) {
int mid=(l+r)>>1,u=id[mid];pps=d;
nth_element(tmp+l,tmp+mid,tmp+r+1);
p[u]=tmp[mid];
if(l<mid)p[u].ls=rebuild(l,mid-1,d^1);
if(r>mid)p[u].rs=rebuild(mid+1,r,d^1);
update(u);return u;
} void recycle(int u) {
id[++top]=u;
int ls=p[u].ls,rs=p[u].rs;
p[u].mn[0]=p[u].mn[1]=inf;
p[u].mx[0]=p[u].mx[1]=-inf;
p[u].siz=1,p[u].ls=p[u].rs=0;
tmp[top]=p[u];
if(ls)recycle(ls);
if(rs)recycle(rs);
} void check(int &u,int d) {
if(!u)return;
int ls=p[u].ls,rs=p[u].rs;
if(max(p[ls].siz,p[rs].siz)>alpha*p[u].siz) {
top=0,recycle(u),u=rebuild(1,top,0);return;
}
int num=d?Y1:X1;
if(num<p[u].c[d])check(p[u].ls,d^1);
else check(p[u].rs,d^1);
} void query(int u) {
if(bo11||bo12)return;
if(bo21&&bo22) {cnt+=p[u].siz;return;}
if(bo31&&bo32) cnt++;
if(p[u].ls)query(p[u].ls);
if(p[u].rs)query(p[u].rs);
}
}kd; struct segment_tree {
int tot;
int ls[maxn*20],rs[maxn*20],rt[maxn*20]; void ins() {
int l=1,r=1e9,p=1,bo=1;
while(1) {
if(bo)kd.ins(rt[p],0),kd.check(rt[p],0);
if(l==r)break;
int mid=(l+r)>>1;
if(k<=mid) {
if(!ls[p])ls[p]=++tot;
r=mid,p=ls[p],bo=0;
}
else {
if(!rs[p])rs[p]=++tot;
l=mid+1,p=rs[p],bo=1;
}
}
} void query() {
cnt=0;kd.query(rt[1]);
if(cnt<k) {
puts("NAIVE!ORZzyz.");
ans=0;return;
}
int l=1,r=1e9,p=1;
while(1) {
if(l==r)break;
int mid=(l+r)>>1;
cnt=0;kd.query(rt[rs[p]]);
if(cnt>=k)l=mid+1,p=rs[p];
else r=mid,p=ls[p],k-=cnt;
}
ans=l;printf("%d\n",ans);
}
}T; int main() {
n=read(),m=read();T.tot=1;
kd.p[0].mn[0]=kd.p[0].mn[1]=inf;
kd.p[0].mx[0]=kd.p[0].mx[1]=-inf;
while(m--) {
int opt=read();X1=read()^ans,Y1=read()^ans;
if(opt==1)k=read()^ans,T.ins();
else {
X2=read()^ans,Y2=read()^ans,k=read()^ans;
T.query();
}
}
return 0;
}

BZOJ4605:崂山白花蛇草水的更多相关文章

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

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

  2. BZOJ4605 : 崂山白花蛇草水

    外层维护权值线段树,内层维护kd-tree. 修改的时候只往右儿子里插入,不平衡的时候替罪羊式重构. 查询的时候在外层线段树上走,在内层kd-tree上查询矩形内点数即可. 时间复杂度$O(q\log ...

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

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

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

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

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

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

  6. LG4848 崂山白花蛇草水

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

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

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

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

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

  9. BZOJ 4605 崂山白花蛇草水(权值线段树+KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4605 [题目大意] 操作 1 x y k 表示在点(x,y)上放置k个物品, 操作 2 ...

随机推荐

  1. 常用的机器学习&数据挖掘知识点

    Basis(基础):MSE(Mean Square Error 均方误差),LMS(LeastMean Square 最小均方),LSM(Least Square Methods 最小二乘法),MLE ...

  2. 主攻ASP.NET.4.5.1 MVC5.0之重生:空地搭建一个包含 Ninject框架 项目

    1.创建一个空白解决方案 2.添加一个类库 名称为XXX.Domain 3.添加一个ASP.MVC 名称为XXX.WebUI 4.选着空模版,勾选MVC核心引用 5.添加单元测试项目XXX.UntiT ...

  3. 12.常见模块time、json模块

    1.time模块 import time #python中最基本的时间模块 time.time() #时间戳 (1970年1月1日00:00:00后经过的浮点秒数) time.localtime(ti ...

  4. explicit c++

    C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况 ...

  5. INSPIRED启示录 读书笔记 - 第6章 招聘产品经理

    产品经理应有的特质 个人素质和态度:技术可以学习,素质却难以培养,有些素质是成功的产品经理必不可少的 对产品的热情:对产品有一种本能的热爱,是夜以继日克服困难.完善产品的动力 用户立场:能换位思考,能 ...

  6. JAVA 使用qq邮箱发送邮件

    引入一个架包: gradle( "com.sun.mail:javax.mail:1.5.6", ) 代码如下: private static final String QQ_EM ...

  7. poj 1679 The Unique MST 【次小生成树+100的小数据量】

    题目地址:http://poj.org/problem?id=1679 2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2 Sample Outpu ...

  8. SQL中的5种常用的聚集函数

    首先你要知道 where->group by->having->order by/limit  ,这个就是写sql语句时的顺序  常用的5个聚集函数: Max             ...

  9. hive学习7(条件函数case)

    case函数 语法: CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END 说明:如果a为TRUE,则返回b:如果c为TRUE,则返回d:否则返回e 实例 ...

  10. HRBUST 2072 树上求最大异或路径值

    一个很经典的套路 思想是 F [u,v] = F[1,u] ^ F[1,v] 这样就转化成了n个数两两异或 求最大值 可以用字典树来做 每次用当前数去树中寻求最大xor值 然后把这个数字插进去 就相当 ...