【bzoj3489】 A simple rmq problem k-d树
由于某些原因,我先打了一个错误的树套树,后来打起了$k-d$。接着因不明原因在思路上被卡了很久,在今天中午蹲坑时恍然大悟......
对于一个数字$a_i$,我们可以用一组三维坐标$(i,pre,nxt)$来表示,其中$i$表示该数字下标,$pre$表示在区间$[1,i)$中满足$a[j]=a[i]$的最大$j$,若不存在,则$pre=0$。$nxt$表示在区间$(i,n]$中满足$a[j]=a[i]$的最小$j$,若不存在,则$nxt=n+1$。
接着我们种一棵3-d树去存储这n个点。对于任意一个节点,需存储该节点的数字,以该节点为根的字数中最大的数字,每一维的最小值和最大值。对于一组询问$[l,r]$,答案即为满足第一维在区间$[l,r]$,第二维在区间$[0,l)$,第三维在区间$(r,n+1)$中的所有点上的最大数字。在查询时,直接按照$k-d$的正常查询策略更新答案即可。
时间复杂度:$O(n log n+n^\frac{5}{3})$
警告:若采用此方法,此题建议各位加一个微小的剪枝:假定当前所得到的最大答案为$ans$,若当前访问的字树中最大答案$≤ans$,直接跳过这棵字树即可。(借助该方法极限数据耗时从17.5s降低至1.4s)
#include<bits/stdc++.h>
#define M 210000
using namespace std;
int n,m,D,root;
struct kd{
int a[],max[],min[],now,ans,l,r;
kd(){a[]=a[]=a[]=now=l=r=;min[]=min[]=min[]=;}
kd(int xx,int yy,int zz,int kk){a[]=xx;a[]=yy;a[]=zz;now=kk;}
friend bool operator <(kd a,kd b){
return a.a[D]<b.a[D];
}
}a[M];
void upd(kd &x,kd &y){
for(int i=;i<;i++)
x.max[i]=max(x.max[i],y.max[i]),
x.min[i]=min(x.min[i],y.min[i]);
}
inline int nx(int d){if(d==) return ; return d+;}
void build(int &x,int l,int r,int d){
if(l>r) return; int mid=(l+r)>>;
D=d; nth_element(a+l,a+mid,a+r+); x=mid;
for(int i=;i<;i++) a[x].max[i]=a[x].min[i]=a[x].a[i];
build(a[x].l,l,mid-,nx(d));
build(a[x].r,mid+,r,nx(d));
upd(a[x],a[a[x].l]); upd(a[x],a[a[x].r]);
a[x].ans=max(a[x].now,max(a[a[x].l].ans,a[a[x].r].ans));
}
int ans=;
void query(int x,int l,int r){
if(x==||ans>=a[x].ans||r<a[x].min[]||a[x].max[]<l||l-<a[x].min[]||a[x].max[]<r+) return;
if(l<=a[x].min[]&&a[x].max[]<=r&&a[x].max[]<l&&r<a[x].min[])
{ans=max(ans,a[x].ans); return;}
if(l<=a[x].a[]&&a[x].a[]<=r&&a[x].a[]<l&&r<a[x].a[]) ans=max(ans,a[x].now);
query(a[x].l,l,r); query(a[x].r,l,r);
}
int last[M]={};
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
int x; scanf("%d",&x);
a[i].a[]=i; a[i].now=x;
a[i].a[]=last[x];
a[last[x]].a[]=i;
last[x]=i;
}
for(int i=;i<=n;i++) if(a[i].a[]==) a[i].a[]=n+;
build(root,,n,);
while(m--){
int x,y,l,r; scanf("%d%d",&x,&y);
l=(x+ans)%n+; r=(y+ans)%n+; if(l>r) swap(l,r);
ans=; query(root,l,r);
printf("%d\n",ans);
}
}
【bzoj3489】 A simple rmq problem k-d树的更多相关文章
- bzoj3489: A simple rmq problem (主席树)
//========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/ 转载要声明! //=============== ...
- bzoj3489 A simple rmq problem 可持久化树套树
先预处理出两个个数组pre,next.pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0:next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1.那么一个满足在区间[L,R] ...
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
- 【BZOJ3489】A simple rmq problem【kd树】
题意 给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. 分析 预处理 ...
- BZOJ3489: A simple rmq problem
设$i$的前驱为$p_i$,后继为$q_i$,把询问看成点$(L,R)$,有贡献的$i$满足$L\in(p_i,i]$且$R\in[i,q_i)$,询问的就是覆盖这个点的矩形的最大值.那么可以用可持久 ...
- 【kd-tree】bzoj3489 A simple rmq problem
Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre ...
- BZOJ3489 A simple rmq problem K-D Tree
传送门 什么可持久化树套树才不会写呢,K-D Tree大法吼啊 对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个 ...
- 【BZOJ3489】A simple rmq problem
[BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...
- bzoj 3489: A simple rmq problem k-d树思想大暴力
3489: A simple rmq problem Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 551 Solved: 170[Submit][ ...
- 【BZOJ3489】A simple rmq problem(KD-Tree)
[BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...
随机推荐
- pthread_once 和 pthread_key
http://blog.csdn.net/rickyguo/article/details/6259410 一次性初始化 有时候我们需要对一些posix变量只进行一次初始化,如线程键(我下面会讲到). ...
- list集合如何对里面的元素进行排序
Collections 是集合的公共类,提供各种工具,其中提供了排序方法. Collections.sort(),方法两个参数,1,要排序的集合,2.排序方式 下面是匿名内部类,实现了排序借口,你也可 ...
- mysql实现分页的几种方式
mysql实现分页的几种方式: 第一种:使用框架自带的pageable来进行分页 package com.cellstrain.icell.repository.repositoryImpl; imp ...
- UVa 1639 Candy (数学期望+组合数学+高精度存储)
题意:有两个盒子各有n个糖,每次随机选一个(概率分别为p,1-p),然后吃掉,直到有一次,你打开盒子发现,没糖了! 输入n,p,求另一个盒子里糖的个数的数学期望. 析:先不说这个题多坑,首先要用lon ...
- 常见XML解析器
xpp3 官网 http://www.extreme.indiana.edu/xgws/xsoap/xpp/ 简介 Xml Pull Parser (in short XPP) is a stream ...
- MFC中开发ocx控件,html容器收不到ocx的事件Event
问题背景: MFC开发ocx控件,主窗口就是ctrl类,主窗口类中调度接口和事件映射添加,执行OK,外部html容器中接收事件成功,如下: ctrl.h中声明事件映射函数 void EVTPENSIG ...
- bootstrap collaspe
和modal类似:也是通过data-toggle, data-target来指定: 可以把折叠插件改为手风琴,如果指定data-parent,那这个data-parent元素下的折叠插件就会像手风琴一 ...
- 基于SketchUp和Unity3D的虚拟场景漫游和场景互动
这是上学期的一次课程作业,难度不高但是也一并记录下来,偷懒地拿课程报告改改发上来. 课程要求:使用sketchUp建模,在Unity3D中实现场景漫游和场景互动. 知识点:建模.官方第一人称控制器.网 ...
- EBS查找当前Form文件
http://www.cnblogs.com/benio/archive/2011/06/10/2077289.html 我们经常会要在ORACLE EBS中寻找我们正在浏览的form页面的执行文件, ...
- Linux服务器目录空间不足解决措施
一般情况下工作环境中我们的服务或数据库文件都会存储在一个单独挂载的分区中,一般占空间比较大的大多就是服务的运行日志以及数据库文件,当我们分区的可用空间不足时就需要我们对分区进行扩容,或者找其它方法 ...