【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 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...
随机推荐
- 如果程序集是从 Web 上下载的,即使它存储于本地计算机,Windows 也会将其标记为 Web 文件,http://go.microsoft.com/fwlink/?LinkId=179545
使用Silverlight,经常弄出很多莫名的XXX文件来于Web,神马信任程序集,就Build个程序都那么麻烦,应该在所有发布时注明一些最基本的配置说明,最BT莫过于连下载程序集的地方都找不到. 若 ...
- 前端之css语法3
一 float属性 1 基本的浮动规则: block元素和inline元素在文档流中的排列方式. block元素通常被现实独立的一块,独占一行.多个block元素会各自新起一行,默认block预算宽度 ...
- 2018.09.14 洛谷P3931 SAC E#1 - 一道难题 Tree(树形dp)
传送门 简单dp题. f[i]表示以i为根的子树被割掉的最小值. 那么有: f[i]=min(∑vf[v],dist(i,fa))" role="presentation" ...
- maven随笔
1.在我们项目顶层的POM文件中,我们会看到dependencyManagement元素.通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号.Maven会沿着父子层次向上走, ...
- gridcontrol 图片列异步加载
在gridview中指定一列,将ColumnEdit设置成pictureEdit 在使用showDialog这里窗体后,需要frm.Dispose()将资源释放 1.将该列的UnboundType属性 ...
- javascript对数组分页
function pagination(pageNo, pageSize, array) { var offset = (pageNo - 1) * pageSize; return (offset ...
- HDU 2058 The sum problem (数学+暴力)
题意:给定一个N和M,N表示从1到N的连续序列,让你求在1到N这个序列中连续子序列的和为M的子序列区间. 析:很明显最直接的方法就是暴力,可是不幸的是,由于N,M太大了,肯定会TLE的.所以我们就想能 ...
- wadl 的自动生成(cxf版本3.1.1)
官方文档 http://cxf.apache.org/docs/jaxrs-services-description.html 举例: package cn.zno; import javax.ws. ...
- day06(Collection,List,ArrayList,LinkedList,iterator迭代器,增强for)
Collection 接口 方法实现 boolean add(Object o);//添加 boolean remove(Object o);//移除 修改方法 让实现类自己去实现修 ...
- hdu 2845 Beans 2016-09-12 17:17 23人阅读 评论(0) 收藏
Beans Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...