[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 ...
随机推荐
- 关于无光盘无u盘状态下该如何安装系统
看到好东西,跟大家分享一下,需要装系统的可以作为参考资料 无光盘无u盘状态下该如何安装系统 重点 : 安装虚拟光驱(用来打开镜像文件) 一个你要安装的系统文件的iso镜像文件 http://www. ...
- Android开发实例-健康食谱应用(一)
转载请注明出处:http://blog.csdn.net/einarzhang/article/details/44774635 本系列文章的重点是如何使用Android开发一个简单的健康食谱软件.使 ...
- Android 手动显示和隐藏软键盘
1.方法一(如果输入法在窗口上已经显示,则隐藏,反之则显示) InputMethodManager imm = (InputMethodManager) getSystemService(Contex ...
- hadoop文件的序列化
目录 1.为什么要序列化? 2.什么是序列化? 3.为什么不用Java的序列化? 4.为什么序列化对Hadoop很重要? 5.Hadoop中定义哪些序列化相关的接口呢? 6.Hadoop 自定义Wri ...
- jboss 7 as1 日志配置
原文地址:https://docs.jboss.org/author/display/AS71/Logging+Configuration Overview The overall server lo ...
- iOS-#ifdef DEBUG代码块介绍
iOS-#ifdef DEBUG宏定义介绍 一.#ifdef DEBUG代码块 #ifdef DEBUG // Debug 模式的代码... #else // Release 模式的代码... #en ...
- C# 如何创建接口以及使用接口的简单Demo(转载!)
//No:1 首先,我们要封装一个接口,接口中不要实现具体的方法(说白了这就是一个架子而已!) using System;using System.Collections.Generic;using ...
- opencart 模块开发详解
opencart 模块开发详解 由 xiekanxiyang » 2013年 7月 11日 10:17 pm opencart 将页面分成若干模块, 每个模块可以有多个实例(可能这样说不是很恰当) 每 ...
- Strut2 采用token机制防御CSRF同时也可以防止表单重复提交
一 未配置Struts2 token的情况下测试 1.从表单提交数据,可以从下图看出,快速点击保存按钮,请求提交了两次 2.检查post提交的数据中未含有token参数 3.查看数据列表,有重复数据 ...
- C++函数二义性问题,我怎么感觉编译器有偷懒嫌疑!!!
瞎扯一段,讲得不一定对.纯属学习! struct BB{ void a(){ cout << "bb's a()\n"; }}; struct B1 : public ...