bzoj3489: A simple rmq problem (主席树)
//==========================
蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/ 转载要声明!
//==========================
说好的“因为是OJ上的题,就简单点好了。”呢?
一开始看不懂,不会写。
然后跪了一个晚上决定看云的题解&……似乎是主席树套主席树!吓傻,还开了40000000的数组。然后一交tle……
然后p是不可能玩常数的。
找不到其他做法。
然后找到了神牛dwjshift,好心地提供了题解(http://tieba.baidu.com/p/2947256742#47989538012l )之后还好心地提供了代码!简直业界良心!(dwj必拿AU)
一开始写的是主席树套配对堆(因为要个优先队列嘛)然后发现套个配对堆各种问题(就不说了,其实主要还是我太弱,这个里面很恶心。。。。。)
然后就跪了dwj的代码,用treap实现。
关于题解,正题开始:
主席树套主席树的做法详见帖子中吧主的话
然后发现没有那么必要。
主席树套优先队列详见帖子下面。
“给定一个序列,支持两个操作: 1.给区间[l,r]中塞进或去掉一个数 2.查询某个点的值”
然后类似标记永久化。就可以变成单点修改的线段树套优先队列了
(原来主席树也是可以区间修改区间查询?……只要套个标记永久化)
写的时候有个地方傻叉了,就是主席树修改的时候,如果区间被要修改的区间覆盖时就不用改他儿子,这时候注意不要忘记儿子们=旧的点的儿子们,要是一开始新的点的儿子都是旧的点的不就行了,这是个人风格问题!)
{$inline on}
const
maxn=;
maxm=;
var
left,right,size,fix,max2,value:array[..maxm]of longint;
root,lson,rson,max:array[..maxm]of longint;
time,last,next,num:array[..maxn]of longint;
n,m,tot1,tot2,ll,rr:longint;
flag:boolean;
procedure swap(var x,y:longint);inline;
var
i:longint;
begin
i:=x;
x:=y;
y:=i;
end;
function mmax(x,y:longint):longint;inline;
begin
if x<y then exit(y);
exit(x);
end;
procedure update(x:longint);inline;
begin
max2[x]:=mmax(max2[left[x]],max2[right[x]]);
if size[x]> then max2[x]:=mmax(max2[x],value[x]);
end;
procedure leftr(var x:longint);inline;
var
k:longint;
begin
k:=right[x];
right[x]:=left[k];
left[k]:=x;
max2[k]:=max2[x];
update(x);
x:=k;
end;
procedure rightr(var x:longint);inline;
var
k:longint;
begin
k:=left[x];
left[x]:=right[k];
right[k]:=x;
max2[k]:=max2[x];
update(x);
x:=k;
end;
procedure insert(var x:longint;y:longint);inline;
begin
if x= then begin
inc(tot2);
x:=tot2;
size[x]:=;
value[x]:=y;
fix[x]:=random(maxn);
max2[x]:=y;
left[x]:=;
right[x]:=;
exit;
end;
if value[x]=y then begin
if flag then inc(size[x])
else dec(size[x]);
update(x);
end
else
if value[x]<y then begin
insert(right[x],y);
update(x);
if fix[right[x]]>fix[x] then leftr(x);
end
else begin
insert(left[x],y);
update(x);
if fix[left[x]]>fix[x] then rightr(x);
end;
end;
procedure change(x,old,l,r,y:longint;var new:longint);inline;
var
mid:longint;
begin
inc(tot1);
new:=tot1;
if (ll<=l) and (r<=rr) then begin
insert(root[x],y);
max[new]:=max2[root[x]];
lson[new]:=lson[old];
rson[new]:=rson[old];
exit;
end;
max[new]:=max2[root[x]];
mid:=(l+r)>>;
if ll>mid then begin
change(x<<+,rson[old],mid+,r,y,rson[new]);
lson[new]:=lson[old];
end
else
if rr<=mid then begin
change(x<<,lson[old],l,mid,y,lson[new]);
rson[new]:=rson[old];
end
else begin
change(x<<,lson[old],l,mid,y,lson[new]);
change(x<<+,rson[old],mid+,r,y,rson[new]);
end;
end;
function query(x,l,r,y:longint):longint;inline;
var
mid:longint;
begin
//writeln(x);
if l=r then exit(max[x]);
mid:=(l+r)>>;
if y>mid then exit(mmax(max[x],query(rson[x],mid+,r,y)))
else exit(mmax(max[x],query(lson[x],l,mid,y)))
end;
procedure into;inline;
var
i,j:longint;
begin
readln(n,m);
for i:= to n do read(num[i]);
for i:= to n do last[i]:=n+;
for i:=n downto do begin
next[i]:=last[num[i]];
last[num[i]]:=i;
end;
for i:= to n do
if last[i]<>n+ then begin
ll:=last[i];
rr:=next[ll]-;
flag:=true;
change(,time[],,n,i,time[]);
end;
for i:= to n do begin
ll:=i-;
rr:=next[i-]-;
flag:=false;
change(,time[i-],,n,num[i-],time[i]);
if next[i-]<>n+ then begin
ll:=next[i-];
rr:=next[ll]-;
flag:=true;
change(,time[i],,n,num[i-],time[i]);
end;
end;
end;
procedure work;inline;
var
lastans,l,r:longint;
begin
lastans:=;
while m> do begin
// writeln(m,'===========');
dec(m);
readln(l,r);
l:=(l+lastans) mod n+;
r:=(r+lastans) mod n+;
if l>r then swap(l,r);
lastans:=query(time[l],,n,r);
writeln(lastans);
end;
end;
begin
randomize;
into;
work;
end.
bzoj3489: A simple rmq problem (主席树)的更多相关文章
- 【题解】BZOJ3489 A Hard RMQ problem(主席树套主席树)
[题解]A simple RMQ problem 占坑,免得咕咕咕了,争取在2h内写出代码 upd:由于博主太菜而且硬是要用指针写两个主席树,所以延后2hQAQ upd:由于博主太菜而且太懒所以他决定 ...
- bzoj 3489 A simple rmq problem——主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...
- BZOJ.3489.A simple rmq problem(主席树 Heap)
题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...
- bzoj 3489 A simple rmq problem —— 主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
- 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 可持久化树套树
先预处理出两个个数组pre,next.pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0:next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1.那么一个满足在区间[L,R] ...
- 【bzoj3489】 A simple rmq problem k-d树
由于某些原因,我先打了一个错误的树套树,后来打起了$k-d$.接着因不明原因在思路上被卡了很久,在今天中午蹲坑时恍然大悟...... 对于一个数字$a_i$,我们可以用一组三维坐标$(i,pre,nx ...
- bzoj 3489 A simple rmq problem - 线段树
Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...
随机推荐
- Homebrew安装Redis找不到redis.conf文件
使用Homebrew安装redis完成后,使用命令 redis-server 启动redis,如下图所示: 启动信息中存在一条警告信息:没有指定的配置文件 然而在安装目录中并没有发现redis.con ...
- 利尔达CC3200模块第一篇之-wlan_ap例程测试
1. 本次采用利尔达的CC3200模块,CC3200主时钟80M,内部没有flash,必须外接SPI Flash.本次测试采用利尔达科技的CC3200的底板和模块(左边).烧写连接VCC, GND, ...
- 华为LiteOS系统使用-任务调度函数-第一篇
1.最近项目遇到华为的LiteOS小型操作系统,使用学习 2. 先打开一个工程LiteOS_Kernel-master\projects\LPC824_LITE_KEIL 3. main.c里面2个关 ...
- MySQL 取得字段子串修改
MySQL 中, GeneID 为 GRMZM2G549533_P01,1123,45 , 需要修改为 GRMZM2G549533_P01 update test set GeneID=SUBSTRI ...
- Qt 解析EXcel文件
写代码需要将excel中的文件导入到数据库中 网上找到以为大神写的,但是当初没有保存,也没有找到 我几乎是原分不动拔下来的,希望大神莫怪 void AddDialog::readExcel(QStri ...
- Django常用命令总结
安装Django: pip install django 指定版本 pip3 install django==2.0 新建项目: django-admin.py startprject mysite ...
- lintcode100 删除排序数组中的重复数字
删除排序数组中的重复数字 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 您在真实的 ...
- JAVA基础学习之路(二)方法定义,重载,递归
一,方法的定义: package test; public class test1 { public static void main(String args[]) { int result = ad ...
- CodeForces 838B Diverging Directions 兼【20180808模拟测试】t3
描述 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点到达. 2. 接下来的 N-1 ...
- 【Linux 运维】查看网络连接状态信息之netstat和ss命令详解
一.netstat 常用命令详解 通过man netstat可以查看netstat的帮助信息: netstat 命令:用于显示各种网络相关信息,如网络连接,路由表,接口状态,无效连接,组播成员 等等. ...