bzoj2724
分块大法好!
首先预处理第i块到第j块的答案,这是可以在O(n*tot)内处理出来的 tot表示块数
然后考虑询问对于[l,r],答案只可能是[l,r]之间所夹整块[i,j]的答案和非整块中的位置上的数
下面我们要做的是快速求出一个数在区间[l,r]出现的次数
当然我一无脑就直接写了主席树,这当然可以复杂度为O(size*logn)
一开始TLE了,好来发现块大小为sqrt(n/log(n))最优,然后跑了20s就过了
后来一想,不对,直接预处理每个数在块1..i出现的次数不就可以了吗
这样求出一个数在区间[l,r]出现的次数只需要O(1)的时间,复杂度仅仅是O(size)
好像是的……这样可以在O(nsqrt(n))的时间内搞出来,这次只跑了7s左右
下面给出算法二
const maxn=; var f:array[..,..maxn] of longint;
a1,a2:array[..,..] of longint;
be,h,s,a,b,c,rank:array[..maxn] of longint;
ans,x,y,i,p,q,m,t,tot,size,n:longint; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=b[(l+r) div ];
repeat
while b[i]<x do inc(i);
while x<b[j] do dec(j);
if not(i>j) then
begin
swap(b[i],b[j]);
swap(c[i],c[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure clear(l,r:longint);
var i:longint;
begin
for i:=l to r do
s[rank[i]]:=-;
end; procedure pre;
var i,j,p,q:longint;
begin
for i:= to tot do //预处理在1..i的块中数出现的次数
begin
p:=i*size;
if p>n then p:=n;
for j:=(i-)*size+ to p do
inc(s[rank[j]]);
for j:= to m do
f[i,j]:=s[j];
end;
for i:= to tot do //预处理i~j块的答案
begin
p:=;
q:=;
fillchar(s,sizeof(s),);
for j:=(i-)*size+ to n do
begin
inc(s[rank[j]]);
if (s[rank[j]]>p) or ((s[rank[j]]=p) and (a[j]<q)) then
begin
p:=s[rank[j]];
q:=a[j];
end;
a1[i,be[j]]:=p;
a2[i,be[j]]:=q;
end;
end;
fillchar(s,sizeof(s),);
end; function ask(x,y:longint):longint;
var i,p,q,w:longint;
begin
if be[x]=be[y] then
begin
p:=;
q:=;
for i:=x to y do
begin
if s[rank[i]]=- then s[rank[i]]:=;
inc(s[rank[i]]);
if (s[rank[i]]>p) or (s[rank[i]]=p) and (a[i]<q) then
begin
p:=s[rank[i]];
q:=a[i];
end;
end;
clear(x,y);
exit(q);
end
else begin
p:=a1[be[x]+,be[y]-];
q:=a2[be[x]+,be[y]-];
for i:=x to be[x]*size do
begin
if s[rank[i]]=- then s[rank[i]]:=f[be[y]-,rank[i]]-f[be[x],rank[i]];
inc(s[rank[i]]); //关键
if (s[rank[i]]>p) or (s[rank[i]]=p) and (a[i]<q) then
begin
p:=s[rank[i]];
q:=a[i];
end;
end;
for i:=(be[y]-)*size+ to y do
begin
if s[rank[i]]=- then s[rank[i]]:=f[be[y]-,rank[i]]-f[be[x],rank[i]];
inc(s[rank[i]]);
if (s[rank[i]]>p) or (s[rank[i]]=p) and (a[i]<q) then
begin
p:=s[rank[i]];
q:=a[i];
end;
end;
clear(x,be[x]*size); //一点常数优化,不用fillchar
clear((be[y]-)*size+,y);
exit(q);
end;
end; begin
readln(n,q);
size:=trunc(sqrt(n));
for i:= to n do
begin
read(a[i]);
be[i]:=(i-) div size+;
b[i]:=a[i];
c[i]:=i;
end;
tot:=n div size;
if n mod size<> then inc(tot);
sort(,n);
m:=;
rank[c[]]:=;
for i:= to n do
begin
if b[i]<>b[i-] then inc(m);
rank[c[i]]:=m;
end;
pre;
t:=;
ans:=;
for i:= to q do
begin
readln(x,y);
x:=(x+ans-) mod n+;
y:=(y+ans-) mod n+;
if x>y then swap(x,y);
ans:=ask(x,y);
writeln(ans);
end;
end.
bzoj2724的更多相关文章
- [BZOJ2724][Violet 6]蒲公英
[BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...
- BZOJ2724 [Violet 6]蒲公英 分块
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...
- BZOJ2724 [Violet]蒲公英(分块)
区间众数.分块,预处理任意两块间所有数的众数,和每块中所有数的出现次数的前缀和.查询时对不是整块的部分暴力,显然只有这里出现的数可能更新答案.于是可以优美地做到O(n√n). #include< ...
- 【BZOJ2724】蒲公英(分块)
[BZOJ2724]蒲公英(分块) 题面 洛谷 谴责权限题的行为 题解 分块什么的都不会,根本就没写过几次. 复杂度根本不会分析,吓得我赶快来练练. 这题要求的是区间众数,显然没有什么很好的主席树之类 ...
- BZOJ2724 蒲公英 【分块】
BZOJ2724 蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被 ...
- 【BZOJ2724】[Violet 6]蒲公英 分块+二分
[BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...
- 【BZOJ2724】【Violet 6】蒲公英
蒲公英/分块入门九Byhzwer 辣鸡我复制粘贴题面格式极其丑陋,各位看原题面啦. [题目描述] 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成 ...
- BZOJ2724 [Violet]蒲公英 分块
题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...
- 蒲公英(bzoj2724)(分块+区间众数)
Input Output Sample Input 6 3 1 2 3 2 1 2 1 5 3 6 1 5 Sample Output 1 2 1 HINT \(n <= 40000\),$ m ...
随机推荐
- Five ways to maximize Java NIO and NIO.2--reference
Java NIO -- the New Input/Output API package-- was introduced with J2SE 1.4 in 2002. Java NIO's purp ...
- Windows7如何在安全模式下卸载驱动(亲测)
在桌面“我的电脑”上点鼠标右键,选择“属性”,“硬件”,“设备管理器”,找到“显示卡选项”,打开前面的“+”,然后按鼠标右键,选择“卸载”就可以了. (亲测,主板驱动卸载成功启动)
- [转] JavaScript中的属性:如何遍历属性
在JavaScript中,遍历一个对象的属性往往没有在其他语言中遍历一个哈希(有些语言称为字典)的键那么简单.这主要有两个方面的原因:一个是,JavaScript中的对象通常都处在某个原型链中,它会从 ...
- Vector/Arraylist与Linklist的区别
SDK提供了有序集合接口java.util.List的几种实现,其中三种最为人们熟知的是Vector.ArrayList和 LinkedList.有关这些List类的性能差别是一个经常被 ...
- Java基础知识强化之集合框架笔记24:ArrayList存储自定义对象并遍历
1. ArrayList存储自定义对象并遍历 2. 代码示例: Student.java,如下: package cn.itcast_01; public class Student { privat ...
- C#.net时间戳转换
//long ticks = (DateTime.Parse(DateTime.Now.ToString(CultureInfo.InvariantCulture)).ToUniversalTime( ...
- 使用XLinq.XElement读取带Namespace(命名空间)的XML
简介 本文主要介绍通过XELemet去读取含有namespaces(xmlns)的XML,这也是偶然间发现这个问题的,一个群里的小伙伴突然问起这个,以此记录一下. 背景 一个XML文档可能包括来自多个 ...
- 远程推送,集成极光的SDK,证书制造
由于iOS操作系统限制,我们APP在后台不能做操作,也不能接收任何数据,所以需要用推送来接收消息. APNs服务,苹果官方网址:https://developer.apple.com/library/ ...
- JSONKit 在iOS9 arm7 64位下出现的问题
最近遇到了一个关于JSONKit的问题,在项目加了arm7 64位以后,JSONKIT会出现[params JSONString] forKey:@”gson”];报错的情况,如下图 具体原因不太清楚 ...
- AFNetworking自带的解析图片的方法
首先要导入头文件 #import "UIKit+AFNetworking.h" 方法如下: [personImageView setImageWithURL:[NSURL URLW ...