A simple rmq problem

题目大意:给定一个长度为$n$的序列,给出$m$个询问:在$[l,r]$之间找到一个在这个区间里只出现过一次的最大的数。

注释:$1\le n\le 10^5$,$1\le mle 2\cdot 10^5$。


想法:

我的第一想法是莫队。

结果发现是强制在线(离线我也不会...

想了想其实$KD-Tree$还是比较显然的。

我们设$l_i$表示$a_i$上一次出现的位置,$r_i$表示下一次。

紧接着我们把第$i$个数转化为三维坐标轴上的点$(l_i,i,r_i)$。

用$KD-Tree$维护直接查即可。

Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
int v[N],lst[N],dic[N],nxt[N],d,l,r,ans,rt;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0,f=1; char c=nc(); while(c<48) {if(c=='-') f=-1; c=nc();} while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}
inline void Max(int &x,int y) {x=x>y?x:y;}
inline void Min(int &x,int y) {x=x<y?x:y;}
struct Node {int p[3],mx[3],mn[3],ans,size,val,ls,rs;}a[N];
inline bool cmp(const Node &a,const Node &b)
{
for(int i=0;i<3;i++) if(a.p[(d+i)%3]!=b.p[(d+i)%3]) return a.p[(d+i)%3]<b.p[(d+i)%3];
return true;
}
inline void pushup(int x,int k)
{
a[x].size+=a[k].size;
for(int i=0;i<3;i++) Max(a[x].mx[i],a[k].mx[i]),Min(a[x].mn[i],a[k].mn[i]);
Max(a[x].ans,a[k].ans);
}
int build(int l,int r,int now)
{
int mid=(l+r)>>1;
d=now; nth_element(a+l,a+mid,a+r+1,cmp);
for(int i=0;i<3;i++) a[mid].mx[i]=a[mid].mn[i]=a[mid].p[i];
a[mid].ans=a[mid].val;
if(l<mid) a[mid].ls=build(l,mid-1,(now+1)%3),pushup(mid,a[mid].ls);
if(mid<r) a[mid].rs=build(mid+1,r,(now+1)%3),pushup(mid,a[mid].rs);
return mid;
}
bool judge(int x)
{
return a[x].ans>ans&&a[x].mx[0]>=l&&a[x].mn[0]<=r&&a[x].mn[1]<l&&a[x].mx[2]>r;
}
void query(int x)
{
if(!x||!judge(x)) return;
if(a[x].p[0]>=l&&a[x].p[0]<=r&&a[x].p[1]<l&&a[x].p[2]>r) Max(ans,a[x].val);
query(a[x].ls); query(a[x].rs);
}
int main()
{
int n=rd(),m=rd();
for(int i=1;i<=n;i++) v[i]=rd(),lst[i]=dic[v[i]],nxt[dic[v[i]]]=i,dic[v[i]]=i;
for(int i=1;i<=n;i++) a[i].p[0]=i,a[i].p[1]=lst[i],a[i].p[2]=nxt[i]?nxt[i]:n+1,a[i].val=v[i];
rt=build(1,n,0); while(m--)
{
l=(rd()+ans)%n+1,r=(rd()+ans)%n+1; if(l>r) swap(l,r);
ans=0,query(rt); printf("%d\n",ans);
}
return 0;
}

小结:$KD-Tree$虽然是一个暴力,但是它的思想还是非常不错的。

[bzoj3489]A simple rmq problem_KD-Tree的更多相关文章

  1. BZOJ3489 A simple rmq problem 【可持久化树套树】*

    BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...

  2. BZOJ3489 A simple rmq problem K-D Tree

    传送门 什么可持久化树套树才不会写呢,K-D Tree大法吼啊 对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个 ...

  3. 【kd-tree】bzoj3489 A simple rmq problem

    Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre ...

  4. BZOJ3489: A simple rmq problem

    设$i$的前驱为$p_i$,后继为$q_i$,把询问看成点$(L,R)$,有贡献的$i$满足$L\in(p_i,i]$且$R\in[i,q_i)$,询问的就是覆盖这个点的矩形的最大值.那么可以用可持久 ...

  5. bzoj3489 A simple rmq problem 可持久化树套树

    先预处理出两个个数组pre,next.pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0:next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1.那么一个满足在区间[L,R] ...

  6. bzoj3489: A simple rmq problem (主席树)

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

  7. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  8. 【BZOJ3489】A simple rmq problem

    [BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...

  9. 【BZOJ3489】A simple rmq problem kd-tree

    [BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...

随机推荐

  1. Windows10系统切换JDK版本(前提是装了多个版本的JDK)

    由于是直接截屏,等我回过头来整理的时候忘记了文章原来的出处, 如作者本人看到,如有侵权,请联系删除!

  2. VMware Workstation安装CentOS 7和开发环境

    VMware Workstation新建虚拟机 此处使用的是VMware Workstation 10,其安装过程即是常规Windos系统下软件安装方式,略过. 安装完成双击图标: 打开虚拟机主界面: ...

  3. javascript动态创建div循环列表

    动态循环加载列表,实现vue中v-for的效果 效果图: 代码: var noApplicationRecord = document.getElementById('noApplicationRec ...

  4. 掌握Spark机器学习库-02-mllib数据格式

    MLlib 1.MLlib介绍 1)MLlib特点 2)哪些算法 3)阅读官方文档 MLlib提供了哪些: 算法 特征工程 管道 持久化 2.MLlib数据格式 1)本地向量 2)标签数据 3)本地矩 ...

  5. testlink 从1.8.5 升级到 1.9.8

    step1:备份原 1.8.5 的数据库.   step2:分别下载 1.9.0 / 1.9.3 / 1.9.8 的安装包.   step3:分别解压 1.9.0 / 1.9.3 / 1.9.8 成3 ...

  6. java 对sql格式化

    public class SqlFormat{ public static void main(String[] args){ String sql=""; sqlFormat(s ...

  7. mongodb用户权限管理(二)

    数据库 分配用户权限 有了创建语法,和参数说明,接下来开始实践. 注意,还有一点,账号是跟着数据库绑定的,在那个库里授权,就在那个库里验证(auth) 否则会失败 创建 账号管理授权权限 的账号 &g ...

  8. uoj #15. 【NOIP2014】生活大爆炸版石头剪刀布

    石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一 样,则不分胜负.在<生活大爆炸>第二季第 8 集中出现了一种石头剪刀布的升级版游戏. 升级版游戏在传统的石头剪 ...

  9. codeforces_B. Forgery

    http://codeforces.com/contest/1059/problem/B 题意: For simplicity, the signature is represented as an  ...

  10. 认识单文件组件.vue 文件

    vuejs 自定义了一种.vue文件,可以把html, css, js 写到一个文件中,从而实现了对一个组件的封装, 一个.vue 文件就是一个单独的组件.由于.vue文件是自定义的,浏览器不认识,所 ...