BZOJ 3489 A simple rmq problem ——KD-Tree
考前写写板子。
用$(i,pre[i],nxt[i])$来描述一个点,然后就变成了区间求最值的问题。
KD-Tree 由低维转向高维的方法,可以用来敲暴力。
剩下就是KD-Tree的基本操作了。
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define inf 0x3f3f3f3f
#define L t[o].ch[0]
#define R t[o].ch[1]
#define ll long long
#define mp make_pair
#define maxn 200005 int D,a[maxn],n,m,ans,pre[maxn],nxt[maxn],lst[maxn],rt;
int ql,qr;
struct Point{
int d[3],mn[3],mx[3],ch[2],v,vmax;
}t[maxn];//i pre nxt bool operator < (Point a,Point b){return a.d[D]<b.d[D];} void pushup(int o)
{
F(i,0,2) t[o].mx[i]=t[o].mn[i]=t[o].d[i];
F(i,0,2)
{
t[o].mx[i]=max(max(t[L].mx[i],t[R].mx[i]),t[o].mx[i]);
t[o].mn[i]=min(min(t[L].mn[i],t[R].mn[i]),t[o].mn[i]);
}
t[o].vmax=max(t[o].v,max(t[L].vmax,t[R].vmax));
} void init(){F(i,0,2) t[0].mn[i]=inf,t[0].mx[i]=-inf;} int build(int l,int r,int dir)
{
D=dir;int mid=l+r>>1;int o=mid;
nth_element(t+l,t+mid,t+r+1);
L=l<mid?build(l,mid-1,(dir+1)%3):0;
R=r>mid?build(mid+1,r,(dir+1)%3):0;
pushup(o); return o;
} bool in(int o)
{
if (t[o].mx[1]>=ql||t[o].mn[2]<=qr) return 0;
if (t[o].mx[0]>qr||t[o].mx[1]<ql) return 0;
return 1;
} bool pin(int o)
{
if (t[o].d[0]>=ql&&t[o].d[0]<=qr&&t[o].d[1]<ql&&t[o].d[2]>qr) return 1;
return 0;
} bool check(int o)
{
if (t[o].mx[0]<ql||t[o].mn[0]>qr) return 0;
if (t[o].mn[1]>=ql||t[o].mx[2]<=qr) return 0;
return 1;
} void query(int o)
{
if (!o) return;
if (in(o)) {ans=max(ans,t[o].vmax);return;}
if (pin(o)) ans=max(ans,t[o].v);
if (t[L].vmax>t[R].vmax)
{
if (t[L].vmax>ans&&check(L)) query(L);
if (t[R].vmax>ans&&check(R)) query(R);
}
else
{
if (t[R].vmax>ans&&check(R)) query(R);
if (t[L].vmax>ans&&check(L)) query(L);
}
} int main()
{
scanf("%d%d",&n,&m);init();
F(i,1,n) scanf("%d",&a[i]);
F(i,1,n) lst[i]=0;
F(i,1,n) pre[i]=lst[a[i]],lst[a[i]]=i;
F(i,1,n) lst[i]=n+1;
D(i,n,1) nxt[i]=lst[a[i]],lst[a[i]]=i;
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];
rt=build(1,n,0);
F(i,1,m)
{
int x,y;
scanf("%d%d",&x,&y);
ql=min((x+ans)%n+1,(y+ans)%n+1);
qr=max((x+ans)%n+1,(y+ans)%n+1);
ans=0;query(rt);printf("%d\n",ans);
}
return 0;
}
BZOJ 3489 A simple rmq problem ——KD-Tree的更多相关文章
- BZOJ 3489: A simple rmq problem(K-D Tree)
Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2579 Solved: 888[Submit][Status][Discuss] Descripti ...
- 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][ ...
- BZOJ 3489: A simple rmq problem
3489: A simple rmq problem Time Limit: 40 Sec Memory Limit: 600 MBSubmit: 1594 Solved: 520[Submit] ...
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...
- BZOJ3489 A simple rmq problem K-D Tree
传送门 什么可持久化树套树才不会写呢,K-D Tree大法吼啊 对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个 ...
- BZOJ.3489.A simple rmq problem(主席树 Heap)
题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...
- bzoj 3489 A simple rmq problem - 线段树
Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...
- BZOJ 3489 A simple rmq problem(可持久化线段树)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...
- BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...
- bzoj 3489 A simple rmq problem——主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...
随机推荐
- Android(java)学习笔记119:BroadcastReceiver之 短信发送的广播接收者
有时候,我们需要开发出来一个短信监听器,监听用户发送的短信记录,下面就是一个案例,这里同样需要使用广播机制. 下面同样是代码示例,MainActivity.java 和 activity_main. ...
- Android颜色选择器介绍
使用Android的颜色选择器可以让我们的view在不同状态下显示不同的颜色. 1.Android中ListView 选择某项改变该行字体颜色 2.文件位置 res/color/filename.xm ...
- appium---命令行启动appium
在客户端的appium长时间运行的时候,出产生一些数据.日志有可能会对appium的内存有所增长,严重的会使appium产生崩溃,这个时候就推荐使用通过cmd进行运行appium, 安装前提需要安装N ...
- C 语言设计坦克大战(未完成)
//坦克大战 //0.提示界面 //1.边框 //2.指定位置显示自己的坦克 //3.己方坦克随着方向键动起来 //getasynkeustae //Sleep(毫秒) //减少闪烁 //不闪烁Set ...
- 【贪心】bzoj1577: [Usaco2009 Feb]庙会捷运Fair Shuttle
一类经典的线段贪心 Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i ...
- 【AC自动机】bzoj4327: JSOI2012 玄武密码
题目思路没话讲:主要是做题时候的细节和经验 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中 ...
- 编译安装 nginx php swoole
安装之前先 准备环境 yum install gcc gcc-c++ automake pcre pcre-devel zlip zlib-devel openssl openssl-devel 然后 ...
- Springboot @Autowired 无法注入问题
特别提醒:一定要注意文件结构 WebappApplication 一定要在包的最外层,否则Spring无法对所有的类进行托管,会造成@Autowired 无法注入. 1. 添加工具类获取在 Sprin ...
- vue_music:封装scroll.vue组件
在项目中经常用到滚动,结合Better-scroll封装了sroll.vue组件参考链接:https://ustbhuangyi.github.io...http://www.imooc.com/ar ...
- mysql的字符串连接符
以前用SQL Server 连接字符串是用“+”,现在数据库用mysql,写个累加两个字段值SQL语句居然不支持"+",郁闷了半天在网上查下,才知道mysql里的+是数字相加的操作 ...