【洛谷P4168】蒲公英【分块】

洛谷 P4168 [Violet]蒲公英(算法竞赛进阶指南,分块, 离散化) 算法竞赛进阶指南, 227页,分块, 离散化 本题要点: 1、先离散化,编号的大小为 10^9, 而元素个数为 5 * 10^5 2、 分块,将 n 个数值,平均分为 sqrt(n * log(n)) 段。 f[i][j]表示从第i段到第j段,出现最多的蒲公英编号。 3、数组 f[T][T]的计算,详细看代码。 4、 假如区间 [l ,r] 包含3 部分,中间是若干完整的段 [L, R],两边是不完整的段 [l, L), (R, r] , 那么中间部分,直接得到出现最多的是哪个编号(f[L][R]), 并 阅读详情

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P4168
给出一个长度为 n n n的序列, m m m次询问,求区间 [ l , r ] [l,r] [l,r]中的众数。强制在线。


思路:

以下内容参考 l y d lyd lyd《算法竞赛进阶指南》。

先离散化不解释。
分块算法一般都是以“暴力+区间预处理+暴力”的方法做的。所以,我们把 n n n分成 T T T块,每块长度 ⌊ T n ⌋ ⌊\frac{T}{n}⌋ ⌊nT​⌋。
然后预处理出对于任意两个区间内的数字个数。也就是说,对于任意的 1 ≤ l ≤ r ≤ T 1\leq l\leq r\leq T 1≤l≤r≤T,我们用 c n t [ L ] [ R ] [ i ] cnt[L][R][i] cnt[L][R][i]表示块 L ∼ R L\sim R L∼R内数字 i i i的个数。
如何预处理出这一部分?

  • 方法1
    先暴力处理出所有的 c n t [ i ] [ i ] [ j ] cnt[i][i][j] cnt[i][i][j],然后用区间 d p dp dp的思想,求出所有的 c n t [ L ] [ R ] [ j ] cnt[L][R][j] cnt[L][R][j],时间复杂度 O ( T 2 n ) O(T^2n) O(T2n)
  • 方法2
    预处理出 s u m [ R ] [ i ] sum[R][i] sum[R][i]表示区间 1 ∼ R 1\sim R 1∼R之间 i i i的个数。然后用前缀和思想, c n t [ L ] [ R ] [ i ] = s u m [ R ] [ i ] − s u m [ L ] [ i ] cnt[L][R][i]=sum[R][i]-sum[L][i] cnt[L][R][i]=sum[R][i]−sum[L][i]。时间复杂度 O ( T 2 ) O(T^2) O(T2)

同时在预处理 c n t cnt cnt的时候顺便处理出 M a x [ L ] [ R ] Max[L][R] Max[L][R],表示区间众数,然后记录众数的个数。
接下来就是如何处理答案了。
对于任意一组询问,设询问区间 [ l , r ] [l,r] [l,r],那么先记录 q , p q,p q,p分别表示 l , r l,r l,r所在的块。如果 p − q ≤ 1 p-q\leq 1 p−q≤1,那么这两个块中间就没有多余的整块,直接朴素求众数。
否则在 c n t [ q + 1 ] [ p − 1 ] cnt[q+1][p-1] cnt[q+1][p−1]的整块区间中,加上 [ l , R [ q ] ] , [ L [ p ] , r ] [l,R[q]],[L[p],r] [l,R[q]],[L[p],r]之间的数字,然后求出答案。最后再减去加上的数就可以了。


算法时间复杂度为 O ( n T 2 + m T n ) O(nT^2+\frac{mT}{n}) O(nT2+nmT​),空间复杂度为 O ( n T 2 ) O(nT^2) O(nT2)。为了平均时间,不妨设 n T 2 = m T n nT^2=\frac{mT}{n} nT2=nmT​,解得 T ≈ n 3 T≈\sqrt[3]{n} T≈3n ​。此时时间复杂度约为 O ( n 5 3 ) O(n^{\frac{5}{3}}) O(n35​)。


代码:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

const int N=50010;
int a[N],b[N],cnt[40][40][N],L[40],R[40],pos[N],sum[N],Max[40][40][2],be[N];
int n,m,T,x,y,len,tot,last;

int ask(int l,int r)
{
	int ans=0,maxn=0;
	int q=pos[l],p=pos[r];
	if (p-q<=1)
	{
		memset(sum,0,sizeof(sum));
		for (int i=l;i<=r;i++)
		{
			sum[a[i]]++;
			if (sum[a[i]]>maxn||(sum[a[i]]==maxn&&a[i]<ans))
				maxn=sum[a[i]],ans=a[i];
		}
		return ans;
	}
	maxn=Max[q+1][p-1][0];
	ans=Max[q+1][p-1][1];
	for (int i=l;i<=R[q];i++)
	{
		cnt[q+1][p-1][a[i]]++;
		if (cnt[q+1][p-1][a[i]]>maxn||(cnt[q+1][p-1][a[i]]==maxn&&a[i]<ans))
			maxn=cnt[q+1][p-1][a[i]],ans=a[i];
	}
	for (int i=L[p];i<=r;i++)
	{
		cnt[q+1][p-1][a[i]]++;
		if (cnt[q+1][p-1][a[i]]>maxn||(cnt[q+1][p-1][a[i]]==maxn&&a[i]<ans))
			maxn=cnt[q+1][p-1][a[i]],ans=a[i];
	}
	for (int i=l;i<=R[q];i++) cnt[q+1][p-1][a[i]]--;
	for (int i=L[p];i<=r;i++) cnt[q+1][p-1][a[i]]--;
	return ans;
}

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	tot=unique(b+1,b+1+n)-b-1;
	for (int i=1;i<=n;i++)
	{
		x=lower_bound(b+1,b+1+tot,a[i])-b;
		be[x]=a[i];
		a[i]=x;
	}
	T=(int)pow((double)n,1.0/3.0);
	len=n/T;
	if (T*len<n) T++;
	for (int i=1;i<=T;i++)
	{
		L[i]=R[i-1]+1;
		R[i]=min(i*len,n);
		for (int j=L[i];j<=R[i];j++)
		{
			cnt[i][i][a[j]]++;
			if (cnt[i][i][a[j]]>Max[i][i][0]||(cnt[i][i][a[j]]==Max[i][i][0]&&a[j]<Max[i][i][1]))
			{
				Max[i][i][0]=cnt[i][i][a[j]];
				Max[i][i][1]=a[j];
			}
			pos[j]=i;
		}
	}
	for (int k=1;k<T;k++)
		for (int i=1;i<=T-k;i++)
		{
			int j=i+k;
			int mid=(i+j)/2;
			for (int l=1;l<=tot;l++)
			{
				cnt[i][j][l]=cnt[i][mid][l]+cnt[mid+1][j][l];
				if (cnt[i][j][l]>Max[i][j][0])
				{
					Max[i][j][0]=cnt[i][j][l];
					Max[i][j][1]=l;
				}
			}
		}
	while (m--)
	{
		scanf("%d%d",&x,&y);
		x=(x+last-1)%n+1;
		y=(y+last-1)%n+1;
		if (x>y) swap(x,y);
		last=be[ask(x,y)];
		printf("%d\n",last);
	}
	return 0;
}
【老生谈算法】可视化通道流中瞬时涡量场的算法实现与MATLAB源码分析——瞬时涡量场 本文旨在探讨可视化通道流中瞬时涡量场的方法,并通过MATLAB编程实现这一过程。涡量场作为描述流体旋涡强度和方向的重要物理量,对于理解复杂流体运动具有重要意义。本文首先介绍了涡量场的基本概念,随后详细阐述了从测量数据收集到涡量场可视化的完整流程,并给出了相应的MATLAB源码。通过实际运行该源码,我们展示了涡量场的可视化结果,并讨论了其在流动结构识别和动力学行为理解中的应用。关键词: 涡量场;流体运动;MATLAB;可视化;PIV一、引言。 阅读详情

相关推荐

set_data_check专题[使用,report_timing,setup/hold检查]

set_data_check用于约束『数据-对-数据』的『建立保持』时间检查,通常被称为非时序约束 ( non-sequential constraints ), 理论上set_data_check 可以设在任意的两个data pin 上,其中一个pin 称为 constrained pin 类似于寄存器的data pin, 另一个pin 称为related pin 类似于寄存器的clock pin.

cy413026的博客 1万+

【题解】洛谷P4168 [Violet]蒲公英 (分块)

在线求区间众数。 分块练习好题。

Fight_for_NOIP的博客 491

RTX 5090配Ubuntu 24.04踩坑记:手把手搞定OpenVLA-OFT环境(附版本避坑清单)

本文详细记录了在RTX 5090显卡和Ubuntu 24.04系统上部署OpenVLA-OFT环境的完整过程,包括驱动安装、CUDA配置、PyTorch版本选择等关键步骤。提供了经过验证的版本组合清单和常见错误解决方案,帮助开发者高效搭建AI开发环境。

weixin_30342209的博客 465

洛谷 P3396 哈希冲突(根号算法 分块)

P3396 哈希冲突 题目链接 从这篇博客来做的这道题 分析: 看到这个题的数据范围是有点懵,这能怎么做啊? 先看暴力 O(n2)O(n^2)O(n2) , for (int i = x; i <= n; i += p) ans += value[i]; 如果我们做预处理的话,ans[p][x]ans[p][x]ans[p][x] ,%p\%p%p 时余数是 xxx 的位置的和,这样复杂度还是 O(n2)O(n^2)O(n2),查询 O(1)O(1)O(1),会爆炸 然后要降复杂度吧,这里就要

NaNa 276

基于单片机直流电机调速控制系统设计

*单片机设计介绍,基于单片机直流电机调速控制系统设计。

2201_75940997的博客 2779

大数据之数据抽取架构演变过程

而当时我们搭建的Flink集群是基于YARN进行资源管理和调度的,因为YARN中不仅仅包含着FLInk的资源,也有hive,zoozie,hdfs等等的资源,这样容易造成yarn资源的过度使用,容易引起整个底座的cpu以及内存的使用问题,经过排查,主要是由于FLink的使用资源引起的,所以后续就把Flink从整个集群中剥离出来,进行资源的隔离,最后Flink采用了StandAlone HA部署(但是这个目前还是存在问题,后续根据项目进行优化)'topic' = '表名',二、数据抽取架构的演变。

天道酬勤 866

分块

分块 这是第一篇博客。嘿嘿嘿! 首先来说一下什么是分块:        分块,顾名思义,即将数据切分成块。那么,这有什么意义呢?其实,分块是一种优雅的暴力。 这里给出一道例题:洛谷P2801。        以此题为例:    &...

Lewis King的博客 940

python等级考试——一级知识点汇总(不包含turtle画图)

本篇文章是针对中国电子学会青少年编程等级考试的,适合初学者以及青少年编程学习者

weixin_65350557的博客 9024

P4168 (静态分块

P4168 (静态分块 题意:区间众数,强制在线 思路:离线考虑莫队,在线考虑静态分块。块之间的贡献不独立,ans[i][j]ans[i][j]ans[i][j]表示块[i,j][i,j][i,j]中的众数,mx[i][j]mx[i][j]mx[i][j]表示众数的出现次数,通过增量法求解,O(n2/B)O(n^2/B)O(n2/B)考虑块与块之间的影响,用cnt[i][j]cnt[i][j]cnt[i][j]表示前iii个块中jjj的出现次数 查询 用散块暴力更新看是否对整块的答案有所贡献即可 $O(

weixin_45539557的博客 252

从零开始之stm32之CAN通信

CAN通信极简教程(小白友好版),从小白的视角了解并实现简单的STM32F103的CAN通信,直接上手。

qq_30993593的博客 1306

HTML5期末大作业:水果超市网站设计——水果超市(6页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 网购商城设置网页

HTML5期末大作业:水果超市网站设计——水果超市(6页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 网购商城设置网页 常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 明星、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 军事、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他 等网页设计题目, A+水平作业, 可满足大

1712

p4168 蒲公英(离散化+分块+前缀和)

[洛谷p4168 蒲公英] 这是蒻蒻写的第一道紫题,必须记住这个时刻. 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的…… 最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢! 哥哥你要快点回来哦!

qq_51467306的博客 249

Spark Catalog详解

旁边的实习生说:我想要用spark代码中对hive库中的内部表和外部表进行删除(包括数据),咋感觉网上搜了一圈都找不到解决方案啊,spark这么鸡肋吗?我:你应该静下心来好好把spark基础知识进行全面学习。实习生:难道spark有这功能,而我没有学习过?咋弄啊?我:学习一下Spark Catalog。实习生:啥是Catalog啊?Spark Catalog是Spark SQL中的一个元数据管理组件,它提供了一个集中化的存储和查询表、视图和函数的位置。

SunnyRivers 1813

(分块)洛谷 P4168 蒲公英 题解

你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。暴力就是离散化之后搞一个桶记录出现次数,查询最大的编号,时间复杂度。这种区间统计的题目,可能一大段区间要被一个一个地遍历很多次,所以可以考虑用。在乡下的小路旁种着许多蒲公英,我们把所有的蒲公英看成一个长度为。查询就是同块直接遍历加桶,不同块就统计两边,也就。内的数据(以离散化后的数据为准,上界为。,那么我们就想查询的时候,计算完。最终的询问区间为计算后的。为一个正整数,表示第。棵蒲公英的种类编号。

m0_60506105的博客 1118

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

洛谷P4168 [Violet]蒲公英【分块】

时空限制 2000ms / 512MB 题目描述 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。 为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 (a_1,a_2…a_n),其中ai为一个正整数,表示第i棵蒲公英的种类编号。 而每次询问一个区间 [l,r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。 注意,你的算...

niiick 241

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【分块】洛谷P4168 蒲公英

链接 https://www.luogu.org/problemnew/show/P4168 大意 求区间众数 思路 首先来个离散化,然后开个桶 预处理块间众数,然后算个数 若是区间在一块,直接暴力求 若是区间不一起,分开暴力求 输出答案很简单,模拟就可以 我真天才哈哈哈,这样都可以 代码 #include&lt;algorithm&gt; #inclu...

Ajwallet 542

洛谷 - P4168 [Violet]蒲公英(分块+离散化)

题目链接:点击查看 题目大意:给出一个长度为 n 的数列,再给出 m 次查询,每次查询区间 [ l , r ] 内的众数,要求强制在线 题目分析:对于这个题意来说,如果允许离线的话,完全可以用莫队当模板题水过去,但强制在线的话就需要考虑如何分块了 这里只讲一下如何实现大蓝书上的第二个方法吧 首先设将数列 n 分成 T 块,每块的长度为 n / T ,接下来可以预处理出 mode[ l ][ r ] ,代表包含第 l 块到第 r 块在内的这段区间上的众数是多少,时间复杂度为 O( nT) ,空间复杂.

Falcon的博客 780

洛谷 P4168 蒲公英 分块入门

我学分块入门的第二题,其实它应该作为第一题做的 虽然之前做过一道类似的题目:作诗, 但是还是调试了很长的时间, 很多细节的地方经常搞错 看来代码还是得多练 先记录一下代码: 1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<cs...

weixin_30436891的博客 134

分块算法求区间众数 + 洛谷4168 P4168 [Violet]蒲公英

分块算法求众数的主要思路就是,先预处理出任意整个块之间的众数,然后查询的时候O(1)的到L,R区间内整块的众数,然后再暴力枚举左右多余的数中是否有超过整个块中的众数。 P4168 开氧气才能过。 Code: #include &lt;bits/stdc++.h&gt; #define LL long long using namespace std; map&lt;int,int&gt;mp; c...

Dave_lzw的博客 673

P4168 [Violet] 蒲公英 Solution

LG P4168 Solution

pystraf的博客 1037

洛谷 P4168 [Violet]蒲公英(分块)

题意:给你一列数,只会有询问操作,询问区间l,r中的众数是几,如果有多个众数,打印最小的那个 思路:的确不怎么会,一开始想到维护块内的众数,但是如果一个块中有很多众数就不知道该怎么办了,看了hzw聚聚的博客以后才知道,我们对于整块,可以提前n2预处理出答案,然后对于不是整块的,我们直接暴力求解就可以了 代码:在洛谷不开氧气过不去啊(为什么写的这么丑) #include <bits/...

weixin_30729609的博客 260

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

题目链接 题目大意:给定\(n\)个数和\(m\)个求区间众数的询问,强制在线 这题我\(debug\)了整整一个下午啊。。-_- 从14:30~16:45终于\(debug\)出来了,\(debug\)的难度主要就在\(Luogu\)数据不能下载,然后\(Contest Hunter\)的数据又太大了(最小的\(n=500,m=1000\)),只能人工查错,一行行检查代码,哎。。。写不出正解还是...

weixin_34358092的博客 114

蒲公英

蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的…… 最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到...

weixin_30446197的博客 276

[Violet]蒲公英

解析 区间众数查询,强制在线。 首先要把a[]离散化。 分块处理。 区间[l, r]的众数,只存在两种情况: (1) 区间[L, R],的众数,L, R为[l, r]内最大块的左右端点。 (2) 区间[l, L - 1]或[R + 1, r]中的数。 情况(1) 可直接预处理。 情况(2) 扫描区间[l, L - 1]或[R + 1, r]中的数,二分查找其在[l, r]中第一次和...

又又大柚纸的博客 496

区间分块-洛谷P4168

表示上一次询问的答案,需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。把所有的蒲公英看成一个长度为。为一个正整数,表示第。棵蒲公英的种类编号。

wbw121124的博客 1687

P4168 [Violet] 蒲公英 题解

P4168 [Violet] 蒲公英 题解

ShiRoZeTsu 1054
上一篇: 【POJ3422】Kaka's Matrix Travels【费用流】
下一篇: 【洛谷P4137】Rmq Problem / mex【主席树】
stoorz1023
博客等级 码龄9年 101粉丝 595原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值