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 ...
随机推荐
- C++编程笔记(多线程学习)
目录 一.线程创建 二.线程的相关操作 2.1 join 2.2 detach 2.3 joinable 三.线程参数 3.1传参所引发的资源回收问题 3.2 将对象的成员函数作为入口函数 四.线程的 ...
- 【Java SE】Day07 API、Scanner类、Random类、ArrayList类
一.API 1.概述: API(Application Programming Interface),应用程序编程接口 Java API:程序员的字典,是类的说明文档 2.使用步骤 帮助文档:JDK_ ...
- 深刻理解JAVA并发中的有序性问题和解决之道
欢迎关注专栏[JAVA并发] 更多技术干活尽在个人公众号--JAVA旭阳 问题 Java并发情况下总是会遇到各种意向不到的问题,比如下面的代码: int num = 0; boolean ready ...
- Vue3 企业级优雅实战 - 组件库框架 - 8 搭建组件库 cli
前面的文章分享了组件库的开发.example.组件库文档,本文分享组件库 cli 开发. 1 为什么要开发组件库 cli 回顾一个新组件的完整开发步骤: 1 在 packages 目录下创建组件目录 ...
- STL set容器常用API
set容器,容器内部将数据自动排序(平衡二叉树),不能插入重复元素.multiset可以插入重复元素.不能修改容器中的值,通过删除值,在插入. #define _CRT_SECURE_NO_WARNI ...
- 万万没想到,go的数据库操作,也能像php一样溜了
Hi,各位go的小伙伴. 很多人都是从php转过来的吧,不知道你们有没有发现,go界的orm并没有像php的orm一样好用.这篇文章里,我们认真的讨论下这个问题,并且会在后面提出解决方案. php的方 ...
- JDBC中文乱码问题
解决JDBC中文数据存入数据库乱码问题 ?useUnicode=true&characterEncoding=utf-8
- [机器学习] PCA主成分分析原理分析和Matlab实现方法
转载于http://blog.csdn.net/guyuealian/article/details/68487833 网上关于PCA(主成分分析)原理和分析的博客很多,本博客并不打算长篇大论推论PC ...
- [OpenCV实战]47 基于OpenCV实现视觉显著性检测
人类具有一种视觉注意机制,即当面对一个场景时,会选择性地忽略不感兴趣的区域,聚焦于感兴趣的区域.这些感兴趣的区域称为显著性区域.视觉显著性检测(Visual Saliency Detection,VS ...
- Python实现单项链表
单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域ele ...