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 ...
随机推荐
- Objective-C中的@Property详解
Objective-C中的@Property详解 @Property (属性) class vairs 这个属性有nonatomic, strong, weak, retain, copy等等 我把它 ...
- 编写android的widget
以前对这个东西很感兴趣,因为确实方便,如今有时间了来做一个例子 首先要定义一个layout(widgetview.xml)和一个配置文件(widgetconfig.xml) <?xml vers ...
- 好用的log
Log.getStackTraceString(new Throwable())
- asp.net对word文档进行修改 对于使用word文档做模板编辑比较适用
最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...
- 关于ASIHTTPRequest连续请求,并发连续,间隔时间很小崩溃问题
在不停的刷新ASIHttpRequest的网络请求时,总是在刷新几次之后,整个app崩溃掉.我的app使用的ARC模式,以为可以自动释放到request的请求.经过摸索,还是需要在dealloc函数加 ...
- C# Dll动态链接库
新建一个类库. 2 编写一个简单的类库实例,例如:DllTest在默认名为:calss1.cs里编写代码一下是一个简单的:在控制台显示 “你以成功调用了动态连接!”sing System;us ...
- webpack学习笔记一(入门)
webpack集成了模块加载和打包等功能 ,这两年在前端领域越来越受欢迎.平时一般是用requirejs.seajs作为模块加载用,用grunt/gulp作为前端构建.webpack作为模块化加载兼容 ...
- JS判断浏览器是否支持某一个CSS3属性的方法
var div = document.createElement('div'); console.log(div.style.transition); //如果支持的话, 会输出 "&quo ...
- topcoder算法练习3
SRM144 DIV1 1100 point Problem Statement NOTE: There are images in the examples section of this ...
- Linux常用命令大全(2)
系统信息arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / ...