[BZOJ 2724] [Violet 6] 蒲公英 【分块】
题目链接:BZOJ - 2724
题目分析
这道题和 BZOJ-2821 作诗 那道题几乎是一样的,就是直接分块,每块大小 sqrt(n) ,然后将数字按照数值为第一关键字,位置为第二关键字排序,方便之后二分查找某个值在某个区间内出现的次数。
预处理出 f[i][j] 即从第 i 块到第 j 块的答案。
对于每个询问,中间的整块直接用预处理出的,两端的 sqrtn 级别的数暴力做,用二分查找它们出现的次数。
每次询问的复杂度是 sqrtn * logn 。
注意:写代码的时候又出现了给 sort 写的 Cmp() 不保证双向一致的错误!!Warning!注意代码中的 Cmp_Num() 函数,即使在不需要第二关键字的情况下,由于 Num 可能会有相同的,也必须加第二关键字以保证比较结果双向一致!
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath> using namespace std; inline void Read(int &Num) {
char c; c = getchar();
while (c < '0' || c > '9') c = getchar();
Num = c - '0'; c = getchar();
while (c >= '0' && c <= '9') {
Num = Num * 10 + c - '0';
c = getchar();
}
} const int MaxN = 40000 + 5, MaxBlk = 200 + 5; int n, m, BlkSize, TotBlk;
int A[MaxN], TL[MaxN], T[MaxN], Cnt[MaxN], L[MaxBlk], R[MaxBlk], First[MaxN], Last[MaxN];
int f[MaxBlk][MaxBlk], g[MaxBlk][MaxBlk]; struct ES
{
int Pos, Num, v;
} E[MaxN]; inline bool Cmp_Num(ES e1, ES e2) {
if (e1.Num == e2.Num) return e1.Pos < e2.Pos;
return e1.Num < e2.Num;
}
inline bool Cmp_Pos(ES e1, ES e2) {return e1.Pos < e2.Pos;} int GetNum(int Num, int x, int y) {
if (x > y || x > E[Last[Num]].Pos || y < E[First[Num]].Pos) return 0;
int l, r, mid, p1, p2;
l = First[Num]; r = Last[Num];
while (l <= r) {
mid = (l + r) >> 1;
if (E[mid].Pos >= x) {
p1 = mid;
r = mid - 1;
}
else l = mid + 1;
}
l = First[Num]; r = Last[Num];
while (l <= r) {
mid = (l + r) >> 1;
if (E[mid].Pos <= y) {
p2 = mid;
l = mid + 1;
}
else r = mid - 1;
}
return p2 - p1 + 1;
} int main()
{
Read(n); Read(m);
for (int i = 1; i <= n; ++i) {
Read(E[i].Num);
E[i].Pos = i;
}
sort(E + 1, E + n + 1, Cmp_Num);
int v_Index = 0;
for (int i = 1; i <= n; ++i) {
if (i == 1 || E[i].Num > E[i - 1].Num) ++v_Index;
E[i].v = v_Index;
TL[v_Index] = E[i].Num;
}
sort(E + 1, E + n + 1, Cmp_Pos);
for (int i = 1; i <= n; ++i) A[i] = E[i].v;
sort(E + 1, E + n + 1, Cmp_Num);
for (int i = 1; i <= n; ++i) {
if (First[E[i].v] == 0) First[E[i].v] = i;
Last[E[i].v] = i;
}
BlkSize = (int)sqrt((double)n);
TotBlk = (n - 1) / BlkSize + 1;
for (int i = 1; i <= TotBlk; ++i) {
L[i] = (i - 1) * BlkSize + 1;
R[i] = i * BlkSize;
}
R[TotBlk] = n;
for (int i = 1; i <= TotBlk; ++i) {
for (int j = 1; j <= n; ++j) Cnt[j] = 0;
f[i][i - 1] = 0; g[i][i - 1] = 0;
for (int j = i; j <= TotBlk; ++j) {
f[i][j] = f[i][j - 1];
g[i][j] = g[i][j - 1];
for (int k = L[j]; k <= R[j]; ++k) {
++Cnt[A[k]];
if (Cnt[A[k]] > f[i][j] || (Cnt[A[k]] == f[i][j] && A[k] < g[i][j])) {
f[i][j] = Cnt[A[k]]; g[i][j] = A[k];
}
}
}
}
memset(Cnt, 0, sizeof(Cnt));
for (int i = 1; i <= n; ++i) T[i] = -1;
int l, r, x, y, Ct, Ans, Cu;
Ans = 0;
for (int i = 1; i <= m; ++i) {
Read(l); Read(r);
l = (l + Ans - 1) % n + 1; r = (r + Ans - 1) % n + 1;
if (l > r) swap(l, r);
x = (l - 1) / BlkSize + 1; if (l != L[x]) ++x;
y = (r - 1) / BlkSize + 1; if (r != R[y]) --y;
if (x > y) {
Ct = 0; Ans = 0;
for (int j = l; j <= r; ++j) {
++Cnt[A[j]];
if (Cnt[A[j]] > Ct || (Cnt[A[j]] == Ct && A[j] < Ans)) {
Ct = Cnt[A[j]]; Ans = A[j];
}
}
for (int j = l; j <= r; ++j) --Cnt[A[j]];
}
else {
Ct = f[x][y]; Ans = g[x][y];
for (int j = l; j < L[x]; ++j) {
++Cnt[A[j]];
if (T[A[j]] == -1) T[A[j]] = GetNum(A[j], L[x], R[y]);
Cu = Cnt[A[j]] + T[A[j]];
if (Cu > Ct || (Cu == Ct && A[j] < Ans)) {
Ct = Cu; Ans = A[j];
}
}
for (int j = r; j > R[y]; --j) {
++Cnt[A[j]];
if (T[A[j]] == -1) T[A[j]] = GetNum(A[j], L[x], R[y]);
Cu = Cnt[A[j]] + T[A[j]];
if (Cu > Ct || (Cu == Ct && A[j] < Ans)) {
Ct = Cu; Ans = A[j];
}
}
for (int j = l; j < L[x]; ++j) {--Cnt[A[j]]; T[A[j]] = -1;}
for (int j = r; j > R[y]; --j) {--Cnt[A[j]]; T[A[j]] = -1;}
}
Ans = TL[Ans];
printf("%d\n", Ans);
}
return 0;
}
[BZOJ 2724] [Violet 6] 蒲公英 【分块】的更多相关文章
- BZOJ 2724: [Violet 6]蒲公英( 分块 )
虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...
- BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]
传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...
- BZOJ 2724 [Violet 6]蒲公英(分块)
题意 在线区间众数 思路 预处理出 f[i][j] 即从第 i 块到第 j 块的答案.对于每个询问,中间的整块直接用预处理出的,两端的 sqrtn 级别的数暴力做,用二分查找它们出现的次数.每次询问的 ...
- BZOJ 2724: [Violet 6]蒲公英
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1633 Solved: 563[Submit][Status ...
- BZOJ.2724.[Violet 6]蒲公英(静态分块)
题目链接 区间众数 强制在线 考虑什么样的数会成为众数 如果一个区间S1的众数为x,那么S1与新区间S2的并的众数只会是x或S2中的数 所以我们可以分块先预处理f[i][j]表示第i到第j块的众数 对 ...
- 【刷题】BZOJ 2724 [Violet 6]蒲公英
Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 Output Sample Input ...
- 【BZOJ 2724】 2724: [Violet 6]蒲公英 (区间众数不带修改版本)
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1908 Solved: 678 Description In ...
- 【BZOJ】2724: [Violet 6]蒲公英
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2900 Solved: 1031[Submit][Statu ...
- 【BZOJ2724】[Violet 6]蒲公英 分块+二分
[BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...
随机推荐
- javascript 匿名函数的理解,js括号中括function 如(function(){})
代码如下: (function(){ //这里忽略jQuery所有实现 })(); (function(){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也 ...
- Latex插入图片 分类: LaTex 2014-11-18 20:07 261人阅读 评论(0) 收藏
在Latex中插入图片的方式很多,我这里只介绍自己常用的一种方式,欢迎大家指导. 我习惯于使用graphicx宏包来插入图片,有时候会配合上subfigure宏包来同时插入多幅图片组合. 首先,需要在 ...
- POJ 3094 Quicksum(简单的问题)
[简要题意]:题意是非常easy. 看样能理解 [分析]:略. 读取字符串. // 200K 0Ms #include<iostream> using namespace std; int ...
- 新秀学习Hibernate——简单的增加、删、更改、检查操作
部分博客使用Hibernate单的样例,把数据库的映射显示了出来在上一篇的博客基础上这篇博客讲述怎样利用Hinbernate框架实现简单的数据库操作. 1.增加junit.jar 2.新建一个工具类H ...
- Qt 学习之路:元素布局
上一章我们介绍了 QML 中用于定位的几种元素,被称为定位器.除了定位器,QML 还提供了另外一种用于布局的机制.我们将这种机制成为锚点(anchor).锚点允许我们灵活地设置两个元素的相对位置.它使 ...
- oracle 字符串切割成结果集方法
oracle字符串切割几种方式 方法一: SELECT COLUMN_VALUE FROM TABLE(SYS.ODCIVARCHAR2LIST('1','2','3','4','5')); 方法二: ...
- Rouh set 入门知识3(上下近似集,正负域,边界域)
在RS中,引入两个概念:一个是下近似集,另一个是上近似集.下近似集是指当一个集合不能利用有效的等价关系被恰当的分类是时,则可通过另外的集合来达到这个集合的近似.形式上,设X⊆U是任一子集,R是U上的等 ...
- hibernate中有时候复杂删除有时候可以拆分为两个语句
这个demo是使用原生的sql语句写的,也就是没有调用我在struts中已经写好的公用类common中的增删改查功能,所以要开启事务
- maven占位符
maven占位符默认是${} 也可以自己指定. pom.xml配置如下: <plugin> <groupId>org.apache.maven.plugins</grou ...
- vs2013下的WCFRest 模板开发WCF
在vs2013下使用wcfRestservice40 是安装不成功的,尝试多遍,都是这样.查看以前vs2012做的wcfrest,经过调教,终于在vs2013下也可以了! 1.新建wcf服务应用程序 ...