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 ...
随机推荐
- 关于linux建立u盘legacy启动方式引导
前言 我一直在用linux,但是我在linux制作pe启动盘无法实现,windows有很多制作pe启动盘的软件,如大白菜,u深度什么的,但是linux没有对应的软件,所以我想写一个类似的工具,那么就有 ...
- 《HelloGitHub》第 80 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...
- Duplicate property mapping of xxx found in xx 嵌套异常,重复的属性在映射中发现。
该异常的原意是因为在映射文件中出现了两个一样的属性名: <property name="相同的属性名出现了两次以上" > <property name=" ...
- web项目的开发--第一天
如何分析需求.如何设计.编码实现.测试. 用ssm架构实现CRM项目代码编写. CRM项目: 关键是养成好的编程思想和编程习惯. 技术架构 视图层(view): 展示数据,跟用户交互. html,cs ...
- JavaEE课程复习1--数据库相关操作
〇.本模块内容简介 30=(DB5+前端5+Web Core15+Project5) Junit.注解 MySQL.JDBC.JDBCUtils.c3p0.Druid连接池及工具类.JDBCTempl ...
- 【每日一题】【直接循环&二分查找】2022年2月10日-NC32 求平方根
描述实现函数 int sqrt(int x).计算并返回 x 的平方根(向下取整) 方法1:直接循环 import java.util.*; public class Solution { /** * ...
- swiper3踩坑
1. 公司一个项目里用的 swiper3 然后同一项目下还装了vue-awesome-swiper需求swiper4...研究半天终于搞明白第一个问题 2. 然后我寻思就按照swiper3官网文档来写 ...
- asp前端无法获取后端中select *查询带出来的全部字段
1.环境 前端:ASP.vbscript 后端:vb 数据库:Sql Server 2.问题描述 最近在做需求时碰到一个很奇怪的问题,后端通过select *查询带出来的字段,在前端只能获取到部分字段 ...
- libcamera 简介
libcamera 简介 libcamera 是一个开源的多媒体库,用于在 Linux 操作系统上支持多种摄像头硬件的访问,libcamera 是一个用户空间库,可用于开发基于摄像头的应用程序,如相机 ...
- vulnhub靶场之BUFFEMR: 1.0.1
准备: 攻击机:虚拟机kali.本机win10. 靶机:BUFFEMR: 1.0.1,下载地址:https://download.vulnhub.com/buffemr/BuffEMR-v1.0.1. ...