LG P4168 [Violet]蒲公英
\(\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]蒲公英的更多相关文章
- 洛谷 P4168 [Violet]蒲公英 解题报告
P4168 [Violet]蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多 ...
- P4168 [Violet]蒲公英 区间众数
$ \color{#0066ff}{ 题目描述 }$ 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 \((a_1,a_2.. ...
- 洛谷 P4168 [Violet] 蒲公英
历尽千辛万苦终于AC了这道题目... 我们考虑1个区间\([l,r]\), 被其完整包含的块的区间为\([L,R]\) 那么众数的来源? 1.\([l,L)\)或\((R,r]\)中出现的数字 2.\ ...
- P4168 [Violet]蒲公英
神仙分块题?其实还是很简单的,res[i][j]表示第i块到第j块的众数,然后再用sum[i][j]表示前i块中j这个种类出现的次数,然后分块瞎搞就行了,感觉我写的十分简洁,好评( //author ...
- p4168 [Violet]蒲公英(分块)
区间众数的重题 和数列分块入门9双倍经验还是挺好的 然后开O2水过 好像有不带log的写法啊 之后在补就是咕咕咕 // luogu-judger-enable-o2 #include <cstd ...
- [洛谷P4168][Violet]蒲公英
题目大意:有$n(n\leqslant4\times10^4)$个数,$m(m\leqslant5\times10^4)$个询问,每次问区间$[l,r]$内的众数,若相同输出最小的,强制在线. 题解: ...
- luogu P4168 [Violet]蒲公英
嘟嘟嘟 分块经典题竟然是一道黑题…… 分块求区间众数的大体思想是对于询问区间[L, R],预处理出这中间的整块的众数,然后统计两边零散的数在[L, R]中出现的次数,最后取出现次数最多且最小的数. 因 ...
- Luogu P4168 [Violet]蒲公英 分块
这道题算是好好写了.写了三种方法. 有一个好像是$qwq$$N\sqrt(N)$的方法,,但是恳请大佬们帮我看看为什么这么慢$qwq$(后面的第三种) 注:$pos[i]$表示$i$属于第$pos[i ...
- 「分块系列」「洛谷P4168 [Violet]」蒲公英 解题报告
蒲公英 Description 我们把所有的蒲公英看成一个长度为\(n\)的序列(\(a_1,a_2,...a_n\)),其中\(a_i\)为一个正整数,表示第i棵蒲公英的种类的编号. 每次询问一个区 ...
- 【洛谷 P4168】[Violet]蒲公英(分块)
题目链接 题目大意:给定\(n\)个数和\(m\)个求区间众数的询问,强制在线 这题我\(debug\)了整整一个下午啊..-_- 从14:30~16:45终于\(debug\)出来了,\(debug ...
随机推荐
- python3获取列表逆序的五种方式
前言 我们将这几种方式分为两类,一种是对列表本身进行操作,改变对应内存中的值,另一种是带有返回值的,相当于拷贝了一份 对列表内存中进行操作 sort() 函数 a = [1,2,3,4] a.sort ...
- -webkit-box-orient:vertical 编译报错之autoprefixer问题
由于各大浏览器的兼容问题,autoprefixer 插件 就可以帮我们自动补齐前缀.它和 less.scss 这样的预处理器不同,它属于后置处理器. 预处理器:在打包之前进行处理 后置处理器:在代码打 ...
- Sqoop的介绍和安装
sqoop下载地址:https://share.weiyun.com/woVbfnfS 或者 https://archive.apache.org/dist/sqoop/1.99.7/ Sqoop简介 ...
- Day34:BigDecimal的使用
BigDecimal 在基本数据类型中对于浮点数的计算时会出现精度丢失的情况,这个时候我们采用BigDecimal类来解决精度丢失的问题. public class Test{ public stat ...
- typora软件下载跟安装
typora软件介绍 typora是一款文本编辑器 是目前非常火爆的文本编辑器 [下载地址](Typora 官方中文站 (typoraio.cn)) 安装操作 pj链接 注意:不要更新!!! 安装 路 ...
- HTML笨方法仿写站酷
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- IDEA中给源码添加自己注释——private-notes插件安装使用
一.前言 我们在空闲之余喜欢研究一些经典框架的源码,发现没办法把自己的注释添加上. 会给出提示:File is read-only 很烦,但是为了安全考虑也是没有办法的! 这是一个大佬就写了一个IDE ...
- [OpenCV实战]35 使用Tesseract和OpenCV实现文本识别
目录 1 如何在Ubuntu和windows上安装Tesseract 1.1 在ubuntu18.04上安装Tesseract4 1.2 在Ubuntu 14.04,16.04,17.04,17.10 ...
- 优化if...else...语句
写代码的时候经常遇到这样的场景:根据某个字段值来进行不同的逻辑处理.例如,不同的会员等级在购物时有不同的折扣力度.如果会员的等级很多,那么代码中与之相关的if...elseif...else...会特 ...
- LRU 缓存
力扣题目 146. LRU 缓存 实现 LRU 缓存需要用到哈希链表 LinkedHashMap. LinkedHashMap 是由哈希表和双链表结合而成的,它的结构如下所示. 用自带的 Linked ...