\(\text{Problem}\)

强制在线静态询问区间众数

\(\text{Solution}\)

不得不说 \(vector\) 是真的慢

做 \(LOJ\) 数列分块入门 \(9\) 卡时间卡了两个小时没成功

说说够快得做法

对原数列分块

考虑已经预处理出任意两块之间得答案

散块中出现的颜色可以让其在整块中失败后翻盘

其它颜色就没机会了

也就是说只考虑散块中出现的颜色和整块预处理出的答案

暴力扫散块,再加上它在整块中的个数就是它的出现次数,取最大值即可

达成此点还需维护每种颜色在块中的前缀和

在考虑预处理,参考询问方法把块 \(i\) 到 \(j\) 的答案看成块 \(i\) 到 \(j-1\) 再多了第 \(j\) 块

于是完成

\(\text{Code}\)

#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#define re register
using namespace std; const int N = 1e5 + 5;
int n, m, lst, st[N], ed[N], id[N], a[N], b[N], f[401][401], buc[N], PreSum[N][401]; inline int Count(int c, int l, int r){return PreSum[c][r] - PreSum[c][l - 1];}
inline void Prework()
{
sort(b + 1, b + n + 1);
int num = sqrt(n) + 1, len = unique(b + 1, b + n + 1) - b - 1;
for(re int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
for(re int i = 1; i <= num; i++)
{
st[i] = ed[i - 1] + 1, ed[i] = (i == num ? n : ed[i - 1] + n / num);
for(re int j = 1; j <= len; j++) PreSum[j][i] = PreSum[j][i - 1];
for(re int j = st[i]; j <= ed[i]; j++) id[j] = i, ++PreSum[a[j]][i];
}
for(re int i = 1; i <= num; i++)
for(re int j = i; j <= num; j++)
{
int cl = 0, num = 0, nu;
for(re int k = st[j]; k <= ed[j]; k++)
{
nu = Count(a[k], i, j);
if (nu > num) num = nu, cl = a[k];
else if (nu == num) cl = min(cl, a[k]);
}
if (i ^ j)
{
nu = Count(f[i][j - 1], i, j);
if (nu > num) num = nu, cl = f[i][j - 1];
else if (nu == num) cl = min(cl, f[i][j - 1]);
}
f[i][j] = cl;
}
}
inline int Query(int l, int r)
{
int x = id[l], y = id[r];
if (x == y)
{
int cl = 0, num = 0, cnt = 0, nu;
for(re int k = l; k <= r; ++buc[a[k]], k++);
for(re int k = l; k <= r; k++)
{
nu = buc[a[k]], buc[a[k]] = 0;
if (nu > num) num = nu, cl = a[k];
else if (nu == num) cl = min(cl, a[k]);
}
return b[cl];
}
int cl = f[x + 1][y - 1], num = Count(cl, x + 1, y - 1), nu, cnt = 0;
for(re int k = l; k <= ed[x]; ++buc[a[k]], k++);
for(re int k = st[y]; k <= r; ++buc[a[k]], k++);
for(re int k = l; k <= ed[x]; k++)
{
nu = buc[a[k]] + Count(a[k], x + 1, y - 1), buc[a[k]] = 0;
if (nu > num) num = nu, cl = a[k];
else if (nu == num) cl = min(cl, a[k]);
}
for(re int k = st[y]; k <= r; k++)
{
nu = buc[a[k]] + Count(a[k], x + 1, y - 1), buc[a[k]] = 0;
if (nu > num) num = nu, cl = a[k];
else if (nu == num) cl = min(cl, a[k]);
}
return b[cl];
} inline void read(int &x)
{
x = 0; char ch = getchar(); int f = 1;
for(; !isdigit(ch); f = (ch == '-' ? -1 : f), ch = getchar());
for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
if (f - 1) x = ~x + 1;
} int main()
{
read(n), read(m);
for(re int i = 1; i <= n; i++) read(a[i]), b[i] = a[i];
Prework();
for(re int l, r; m; --m)
{
read(l), read(r), l = (l + lst - 1) % n + 1, r = (r + lst - 1) % n + 1;
if (l > r) swap(l, r);
printf("%d\n", lst = Query(l, r));
}
}

LG P4168 [Violet]蒲公英的更多相关文章

  1. 洛谷 P4168 [Violet]蒲公英 解题报告

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

  2. P4168 [Violet]蒲公英 区间众数

    $ \color{#0066ff}{ 题目描述 }$ 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 \((a_1,a_2.. ...

  3. 洛谷 P4168 [Violet] 蒲公英

    历尽千辛万苦终于AC了这道题目... 我们考虑1个区间\([l,r]\), 被其完整包含的块的区间为\([L,R]\) 那么众数的来源? 1.\([l,L)\)或\((R,r]\)中出现的数字 2.\ ...

  4. P4168 [Violet]蒲公英

    神仙分块题?其实还是很简单的,res[i][j]表示第i块到第j块的众数,然后再用sum[i][j]表示前i块中j这个种类出现的次数,然后分块瞎搞就行了,感觉我写的十分简洁,好评( //author ...

  5. p4168 [Violet]蒲公英(分块)

    区间众数的重题 和数列分块入门9双倍经验还是挺好的 然后开O2水过 好像有不带log的写法啊 之后在补就是咕咕咕 // luogu-judger-enable-o2 #include <cstd ...

  6. [洛谷P4168][Violet]蒲公英

    题目大意:有$n(n\leqslant4\times10^4)$个数,$m(m\leqslant5\times10^4)$个询问,每次问区间$[l,r]$内的众数,若相同输出最小的,强制在线. 题解: ...

  7. luogu P4168 [Violet]蒲公英

    嘟嘟嘟 分块经典题竟然是一道黑题…… 分块求区间众数的大体思想是对于询问区间[L, R],预处理出这中间的整块的众数,然后统计两边零散的数在[L, R]中出现的次数,最后取出现次数最多且最小的数. 因 ...

  8. Luogu P4168 [Violet]蒲公英 分块

    这道题算是好好写了.写了三种方法. 有一个好像是$qwq$$N\sqrt(N)$的方法,,但是恳请大佬们帮我看看为什么这么慢$qwq$(后面的第三种) 注:$pos[i]$表示$i$属于第$pos[i ...

  9. 「分块系列」「洛谷P4168 [Violet]」蒲公英 解题报告

    蒲公英 Description 我们把所有的蒲公英看成一个长度为\(n\)的序列(\(a_1,a_2,...a_n\)),其中\(a_i\)为一个正整数,表示第i棵蒲公英的种类的编号. 每次询问一个区 ...

  10. 【洛谷 P4168】[Violet]蒲公英(分块)

    题目链接 题目大意:给定\(n\)个数和\(m\)个求区间众数的询问,强制在线 这题我\(debug\)了整整一个下午啊..-_- 从14:30~16:45终于\(debug\)出来了,\(debug ...

随机推荐

  1. Java lambda表达式基本使用

    代码示例:java.lambda.LambdaExpression 1 本质 lambda表达式本质上是对匿名内部类实例的一种简化写法. 1.1 案例 有以下List<Integer>对象 ...

  2. C++ 之 宏定义

    宏在 C 语言中非常重要,但在 C++ 中却无甚大用,普遍的共识:尽量避免使用宏 C++ 之父 Bjarne 在<C++ Programming Language>中写到 Avoid ma ...

  3. 数电第一周总结_by_yc

    数电第一周总结 重点:Verilog建模方式 结构级建模: 需基于电路原理图 module mux( input data0, input data1, input sel, output out); ...

  4. 关于Qt的QPixmap中不支持jpg文件格式的问题

    问题 Qt部分版本存在不支持jpg,JPEG等图像格式的问题 qDebug()<<QImageWriter::supportedImageFormats(); 这行代码可以查看所支持的图像 ...

  5. MyBatis02:流程分析、注解、代理dao实现CRUD、参数深入、传统DAO、配置

    今日内容 回顾 mybatis的自定义.分析和环境搭建 完善基于注解的mybatis mybatis的curd(基于代理dao的方式)※ mybatis的参数深入及结果集的深入 mybatis中基于传 ...

  6. 【Impala】概念、原理、内外部shell、建库建表、分区、查询、自定义函数、存储压缩

    一.基本概念 1.介绍 对HDFS.Hbase数据的高性能.低延迟的交互式SQL查询功能 2.优缺点 优点:基于内存运算,无需写入磁盘,无需转化为MR,支持Data Locality调度(数据和计算在 ...

  7. instanceof和Class.isAssignableFrom的区别

    1. Class.isAssignableFrom 偶然看见同事写的一段代码是这样的 if( AfterRender.class.isAssignableFrom( assembly.getClass ...

  8. ChatGPT 会开源吗?

    最近,我被一款叫做 ChatGPT 的人工智能(AI)聊天机器人,刷屏了.网上有人说它是搜索引擎杀手,还有人说它将取代程序员... 最后,我还是没扛住铺天盖地的赞美,跑去注册了个账号,抱着调侃&quo ...

  9. 重学c#系列——linq(3) [二十九]

    前言 继续介绍一些复杂的linq. 正文 groupjoin 这个函数: 有department public class Deployment { public string Id { get; s ...

  10. Python实验报告(第9章)

    实验9:异常处理及程序调试 一.实验目的和要求 1.了解代码异常知识: 2.掌握异常处理的try-except语句.try-except-else语句.try-except-finally语句.rai ...