分块大法好!
首先预处理第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的更多相关文章

  1. [BZOJ2724][Violet 6]蒲公英

    [BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...

  2. BZOJ2724 [Violet 6]蒲公英 分块

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...

  3. BZOJ2724 [Violet]蒲公英(分块)

    区间众数.分块,预处理任意两块间所有数的众数,和每块中所有数的出现次数的前缀和.查询时对不是整块的部分暴力,显然只有这里出现的数可能更新答案.于是可以优美地做到O(n√n). #include< ...

  4. 【BZOJ2724】蒲公英(分块)

    [BZOJ2724]蒲公英(分块) 题面 洛谷 谴责权限题的行为 题解 分块什么的都不会,根本就没写过几次. 复杂度根本不会分析,吓得我赶快来练练. 这题要求的是区间众数,显然没有什么很好的主席树之类 ...

  5. BZOJ2724 蒲公英 【分块】

    BZOJ2724 蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被 ...

  6. 【BZOJ2724】[Violet 6]蒲公英 分块+二分

    [BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...

  7. 【BZOJ2724】【Violet 6】蒲公英

    蒲公英/分块入门九Byhzwer 辣鸡我复制粘贴题面格式极其丑陋,各位看原题面啦. [题目描述] 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成 ...

  8. BZOJ2724 [Violet]蒲公英 分块

    题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...

  9. 蒲公英(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 ...

随机推荐

  1. Java——(九)IO流

    一.流的分类 1.输入流和输出流 按照流的流向来分,可以分为输入流和输出流 输入流:只能从中读取数据,而不能向其写入数据. 输出流:只能向其写入数据,而不能从中读取数据. 此处的输入.输出涉及一个方向 ...

  2. 第三篇:python基础之编码问题

    python基础之编码问题   python基础之编码问题 本节内容 字符串编码问题由来 字符串编码解决方案 1.字符串编码问题由来 由于字符串编码是从ascii--->unicode---&g ...

  3. CakePHP之控制器

    控制器 控制器是MVC中的“C”. 如果你的网站使用Cake框架制作,一般根据url地址和通过路由,就会找到正确的控制器,然后控制器的动作就会被调用. 一个控制器需要解释请求数据.确保使用正确的模型. ...

  4. ASP。net中如何在一个按钮click事件中调用另一个按钮的click事件

    方法一: 直接指定 事件<asp:Button ID="btn1" runat="server" Text="按钮1" onclick ...

  5. left join 和 left outer join 有什么区别?

    left join 是left outer join的简写,left join默认是outer属性的.outer join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行.它还返回任何 ...

  6. oracle命令的缩写原型单词方便记忆总结

    $ORACLE_HOME/bin下的utilities解释 Binary              First Available        Description adapters        ...

  7. java集合之链式操作

    如果用过js/jquery.groovy等语言,大概对这样的代码比较熟悉: [1,2,3].map(function(d){...}).grep(function(d){...}).join(',') ...

  8. asp.net发布和更新网站

    我们一般使用ftp软件来更新网站,而更新之前的一个步骤就是发布项目.以下将讲解asp.net mvc如何发布网站. 打开项目 右键点击项目,选择“发布” 第一次发布前,需要配置一下发布配置文件:点击” ...

  9. hdoj 2049 错排

    代码: #include <stdio.h> int main(){ int n,a,b,i,j; __int64 s[22],h[22]; s[1]=0; s[2]=1; s[3]=2; ...

  10. hdu 3308

    终于A了,我好想砍人,虽然这是一道基础的区间合并.但是这错误我也是醉了. 错误我表在注释里. 题目意思不多说,sha崽题目出的很简洁. #include <iostream>#includ ...