考前写写板子。

用$(i,pre[i],nxt[i])$来描述一个点,然后就变成了区间求最值的问题。

KD-Tree 由低维转向高维的方法,可以用来敲暴力。

剩下就是KD-Tree的基本操作了。

  1. #include <map>
  2. #include <cmath>
  3. #include <queue>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <iostream>
  7. #include <algorithm>
  8. using namespace std;
  9. #define F(i,j,k) for (int i=j;i<=k;++i)
  10. #define D(i,j,k) for (int i=j;i>=k;--i)
  11. #define inf 0x3f3f3f3f
  12. #define L t[o].ch[0]
  13. #define R t[o].ch[1]
  14. #define ll long long
  15. #define mp make_pair
  16. #define maxn 200005
  17.  
  18. int D,a[maxn],n,m,ans,pre[maxn],nxt[maxn],lst[maxn],rt;
  19. int ql,qr;
  20. struct Point{
  21. int d[3],mn[3],mx[3],ch[2],v,vmax;
  22. }t[maxn];//i pre nxt
  23.  
  24. bool operator < (Point a,Point b){return a.d[D]<b.d[D];}
  25.  
  26. void pushup(int o)
  27. {
  28. F(i,0,2) t[o].mx[i]=t[o].mn[i]=t[o].d[i];
  29. F(i,0,2)
  30. {
  31. t[o].mx[i]=max(max(t[L].mx[i],t[R].mx[i]),t[o].mx[i]);
  32. t[o].mn[i]=min(min(t[L].mn[i],t[R].mn[i]),t[o].mn[i]);
  33. }
  34. t[o].vmax=max(t[o].v,max(t[L].vmax,t[R].vmax));
  35. }
  36.  
  37. void init(){F(i,0,2) t[0].mn[i]=inf,t[0].mx[i]=-inf;}
  38.  
  39. int build(int l,int r,int dir)
  40. {
  41. D=dir;int mid=l+r>>1;int o=mid;
  42. nth_element(t+l,t+mid,t+r+1);
  43. L=l<mid?build(l,mid-1,(dir+1)%3):0;
  44. R=r>mid?build(mid+1,r,(dir+1)%3):0;
  45. pushup(o); return o;
  46. }
  47.  
  48. bool in(int o)
  49. {
  50. if (t[o].mx[1]>=ql||t[o].mn[2]<=qr) return 0;
  51. if (t[o].mx[0]>qr||t[o].mx[1]<ql) return 0;
  52. return 1;
  53. }
  54.  
  55. bool pin(int o)
  56. {
  57. if (t[o].d[0]>=ql&&t[o].d[0]<=qr&&t[o].d[1]<ql&&t[o].d[2]>qr) return 1;
  58. return 0;
  59. }
  60.  
  61. bool check(int o)
  62. {
  63. if (t[o].mx[0]<ql||t[o].mn[0]>qr) return 0;
  64. if (t[o].mn[1]>=ql||t[o].mx[2]<=qr) return 0;
  65. return 1;
  66. }
  67.  
  68. void query(int o)
  69. {
  70. if (!o) return;
  71. if (in(o)) {ans=max(ans,t[o].vmax);return;}
  72. if (pin(o)) ans=max(ans,t[o].v);
  73. if (t[L].vmax>t[R].vmax)
  74. {
  75. if (t[L].vmax>ans&&check(L)) query(L);
  76. if (t[R].vmax>ans&&check(R)) query(R);
  77. }
  78. else
  79. {
  80. if (t[R].vmax>ans&&check(R)) query(R);
  81. if (t[L].vmax>ans&&check(L)) query(L);
  82. }
  83. }
  84.  
  85. int main()
  86. {
  87. scanf("%d%d",&n,&m);init();
  88. F(i,1,n) scanf("%d",&a[i]);
  89. F(i,1,n) lst[i]=0;
  90. F(i,1,n) pre[i]=lst[a[i]],lst[a[i]]=i;
  91. F(i,1,n) lst[i]=n+1;
  92. D(i,n,1) nxt[i]=lst[a[i]],lst[a[i]]=i;
  93. F(i,1,n) t[i].d[0]=i,t[i].d[1]=pre[i],t[i].d[2]=nxt[i],t[i].v=a[i];
  94. rt=build(1,n,0);
  95. F(i,1,m)
  96. {
  97. int x,y;
  98. scanf("%d%d",&x,&y);
  99. ql=min((x+ans)%n+1,(y+ans)%n+1);
  100. qr=max((x+ans)%n+1,(y+ans)%n+1);
  101. ans=0;query(rt);printf("%d\n",ans);
  102. }
  103. return 0;
  104. }

  

BZOJ 3489 A simple rmq problem ——KD-Tree的更多相关文章

  1. BZOJ 3489: A simple rmq problem(K-D Tree)

    Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2579  Solved: 888[Submit][Status][Discuss] Descripti ...

  2. 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][ ...

  3. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

  4. [BZOJ 3489] A simple rmq problem 【可持久化树套树】

    题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...

  5. BZOJ3489 A simple rmq problem K-D Tree

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

  6. BZOJ.3489.A simple rmq problem(主席树 Heap)

    题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...

  7. bzoj 3489 A simple rmq problem - 线段树

    Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...

  8. BZOJ 3489 A simple rmq problem(可持久化线段树)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...

  9. BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...

  10. bzoj 3489 A simple rmq problem——主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

随机推荐

  1. HDU 5095 Linearization of the kernel functions in SVM (坑水)

    比较坑的水题,首项前面的符号,-1,+1,只有数字项的时候要输出0. 感受一下这些数据 160 0 0 0 0 0 0 0 0 -10 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 ...

  2. Opencascade术语笔记。

    1. chamfer 倒角 vs fillet  圆角: 2.boolean operatiron(布尔操作): common(相加),fuse(相交),cut(相减): 3.depressions( ...

  3. JSONPath - XPath for JSON

    http://goessner.net/articles/JsonPath/ [edit] [comment] [remove] |2007-02-21| e1 # JSONPath - XPath ...

  4. Mutations-freecodecamp算法题目

    Mutations(比较字符串) 要求 如果数组第一个字符串元素包含了第二个字符串元素的所有字符,函数返回true. 不用考虑大小写和字符顺序 思路 将数组中的两个字符串小写化 将第二个数组元素(第二 ...

  5. 【dp】守望者的逃离

    妙 题目描述 恶魔猎手尤迪安野心勃勃,他背着了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快 ...

  6. LNMP一键安装包开启pathinfo和rewrite模式

    此教程适用于集成安装包lnmp,官网是https://lnmp.org/ 一. 开启pathinfo #注释 下面这一行 #include enable-php.conf #载入新的配置文件 incl ...

  7. 汇编语言 Part 2——寄存器

    处理器操作主要涉及处理数据.这些数据可以存储在内存中并从中访问.但是,读取数据并将其存储到内存中会减慢处理器的速度,因为它涉及将数据请求通过控制总线发送到内存存储单元并通过同一通道获取数据的复杂过程. ...

  8. SQL前后端分页

    /class Page<T> package com.neusoft.bean; import java.util.List; public class Page<T> { p ...

  9. 线段树: CDOJ1598-加帕里公园的friends(区间合并,单点更新)

    加帕里公园的friends Time Limit: 3000/1000MS (Java/Others) Memory Limit: 131072/131072KB (Java/Others) 我还有很 ...

  10. poj 3669 火星撞地球问题 bfs算法

    题意:火星撞地球,你要跑到一个永远安全的地方,求最短时间 思路:bfs+预处理 这题的数据量比较大,所以需要进行预处理 对每个位置设上时间(被撞的最早时间) 未被撞的设为-1 for (int j = ...