【AT1219】历史研究
Problem
Description
\(IOI\)国历史研究的第一人——\(JOI\)教授,最近获得了一份被认为是古代\(IOI\)国的住民写下的日记。\(JOI\)教授为了通过这份日记来研究古代\(IOI\)国的生活,开始着手调查日记中记载的事件。
日记中记录了连续\(N\)天发生的时间,大约每天发生一件。
事件有种类之分。第\(i\)天\((1<=i<=N)\)发生的事件的种类用一个整数\(X_i\)表示,\(X_i\)越大,事件的规模就越大。
\(JOI\)教授决定用如下的方法分析这些日记:
选择日记中连续的一些天作为分析的时间段
事件种类t的重要度为t*(这段时间内重要度为t的事件数)
计算出所有事件种类的重要度,输出其中的最大值 现在你被要求制作一个帮助教授分析的程序,每次给出分析的区间,你需要输出重要度的最大值。
Input Format
第一行两个空格分隔的整数\(N\)和\(Q\),表示日记一共记录了\(N\)天,询问有\(Q\)次。
接下来一行\(N\)个空格分隔的整数\(X_1…X_N\),\(X_i\)表示第\(i\)天发生的事件的种类
接下来\(Q\)行,第\(i\)行\((1<=i<=Q)\)有两个空格分隔整数\(A_i\)和\(B_i\),表示第\(i\)次询问的区间为\([A_i,B_i]\)。
Output Format
输出\(Q\)行,第\(i\)行\((1<=i<=Q)\)一个整数,表示第i次询问的最大重要度
Sample
Input
5 5
9 8 7 8 9
1 2
3 4
4 4
1 4
2 4
Output
9
8
8
16
16
Range
\(1<=N<=105\)
\(1<=Q<=105\)
\(1<=X_i<=109 (1<=i<=N)\)
Algorithm
莫队,回滚莫队,离线询问,排序算吗
Mentality
我们发现对于暴力的数据,我们之所以要套个线段树是因为莫队中的 \(Del\) 操作执行后无法继续保证最大值的维护。那么我们换个思路想一下,我们避免掉 \(Del\) 操作的执行不就好了吗?
这就是回滚莫队的板子了。
对于 \(r-l>=块大小\) 的询问,直接暴力处理。
对于左端点在同一个块内的询问,我们在处理之前先令 \(l\) 处在下一个块的块首,然后不断 \(r++\) 到询问右端点,那么 \(r\) 就保证不会执行 \(Del\) 操作了。而对于 \(l\) ,当前 \(r\) 处理完之后,记录下当前的状态(包括最大值和每个种类的照片数量啥的),我们只需要对于每个询问移动到询问左端点,然后得到答案之后 \(O(1)\) 跳回之前状态即可。
那么对于记录状态与跳回怎么处理呢?表面上看上去记录每个种类照片数量的状态是 \(O(n)\) 的,但是并不是。显然,我们先对于 \(r\) 端跳跃的时候使用数组 \(a\) 记录下每种照片的数量,\(l\) 端跳跃的时候用数组 \(b\) 记录下每种照片的数量。
然后,我们使用 \(t\) 数组记录 \(b\) 中每个元素上次修改是在第几次操作的时候,如果上次修改不是当前操作,那么我们将 \(t\) 数组更新为当前操作值,同时将 \(b\) 数组中当前元素变更为 \(a\) 数组对应下标的元素 。这样我们只要在移动 \(l\) 的时候对 \(b\) 数组进行判断更新即可。
然后输出答案就好了。
Code
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, Q, a[100001], cnt, key[100001], book[2][100001], size, t[100001], now, C;
int L, R, lnow;
long long ans, Ans[100001], maxx, nowmax;
void Max(long long &a, long long b) {
if (b > a) a = b;
}
struct Que {
int l, r, q, d;
} k[100001];
struct number {
int num, d;
} num[100001];
bool cmp(number a, number b) { return a.num < b.num; }
bool cmp2(Que a, Que b) { return a.q != b.q ? a.q < b.q : a.r < b.r; }
long long Pow(int l, int r) {
long long maxx = 0;
int book[100001] = {0};
for (int i = l; i <= r; i++) Max(maxx, 1ll * (++book[a[i]]) * key[a[i]]);
return maxx;
}
void And(int x) {
if (t[a[x]] != now) {
t[a[x]] = now;
book[1][a[x]] = book[0][a[x]];
}
}
void Add(int x) {
And(x);
Max(nowmax, 1ll * (++book[1][a[x]]) * key[a[x]]);
}
void add(int x) { Max(maxx, 1ll * (++book[0][a[x]]) * key[a[x]]); }
int main() {
cin >> n >> Q;
size = sqrt(n);
for (int i = 1; i <= n; i++) {
scanf("%d", &num[i].num);
num[i].d = i;
}
sort(num + 1, num + n + 1, cmp);
for (int i = 1; i <= n; i++) {
if (num[i].num != num[i - 1].num) key[++cnt] = num[i].num;
a[num[i].d] = cnt;
}
for (int i = 1; i <= Q; i++) {
scanf("%d%d", &k[i].l, &k[i].r);
k[i].d = i, k[i].q = k[i].l / size;
if (k[i].r - k[i].l <= size) {
Ans[i] = Pow(k[i].l, k[i].r);
k[i].q = 1e9;
C++;
}
}
sort(k + 1, k + Q + 1, cmp2);
k[0].q = -1;
for (int i = 1; i <= Q - C; i++) {
now++;
if (k[i].q != k[i - 1].q) {
lnow = (k[i].q + 1) * size, nowmax = maxx = 0,
R = (k[i].q + 1) * size - 1;
memset(book, 0, sizeof(book));
}
L = lnow;
while (R < k[i].r) add(++R);
nowmax = maxx;
while (L > k[i].l) Add(--L);
Ans[k[i].d] = nowmax;
}
for (int i = 1; i <= Q; i++) printf("%lld\n", Ans[i]);
}
【AT1219】历史研究的更多相关文章
- bzoj4241/AT1219 历史研究(回滚莫队)
bzoj4241/AT1219 历史研究(回滚莫队) bzoj它爆炸了. luogu 题解时间 我怎么又在做水题. 就是区间带乘数权众数. 经典回滚莫队,一般对于延长区间简单而缩短区间难的莫队题可以考 ...
- BZOJ 4241 历史研究
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
- BZOJ4241 历史研究
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
- BZOJ4241历史研究——回滚莫队
题目描述 IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. 日记中记录了连 ...
- BZOJ4241 历史研究 莫队 堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目 Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JO ...
- BZOJ4241:历史研究(回滚莫队)
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
- [JOISC2014]歴史の研究/[BZOJ4241]历史研究
[JOISC2014]歴史の研究/[BZOJ4241]历史研究 题目大意: 一个长度为\(n(n\le10^5)\)的数列\(A(A_i\le10^9)\),定义一个元素对一个区间\([l,r]\)的 ...
- 【BZOJ4241】历史研究 分块
[BZOJ4241]历史研究 Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开 ...
- [bzoj4241][历史研究] (分块)
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
随机推荐
- yum配置文件中baseurl和mirrorlist的区别
找到yum.repo.d文件夹下的文件,随便打开一个,找到mirrorlist的url,比如: http://mirrorlist.centos.org/?release=6&arch=$ba ...
- 关于setInterval的坑
一道面试题:“setInterval和setTimeout有什么区别” “如果setInterval计时器的回调函数执行完需要5秒,而计时器时间间隔为3秒,那会发生什么?” 验证代码 让程序滞留固定时 ...
- HDU 1527 取石子游戏 (威佐夫博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是 ...
- read 命令详解
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量 语法选项 -p read –p “提示语句”,则屏幕就会输出提示语句,等待输入,并将输入存储在REPLY中 -n ...
- bc 命令
bc命令是一种支持任意精度的交互执行的计算器语言.是Linux简单的计算器,能进行进制转换与计算.能转换的进制包括十六进制.十进制.八进制.二进制等.可以使用的运算符号包括(+)加法.(-)减法.(* ...
- TestNG 搭建测试框架 自动化测试
框架层级及基本组件: 参考:https://www.cnblogs.com/jier888/p/8998724.html Java作为开发语言 Maven管理项目及Jar包 Testng作为测试 ...
- Linux - TCP编程相关配置2
100万并发连接服务器笔记之处理端口数量受限问题 第二个遇到的问题:端口数量受限 一般来说,单独对外提供请求的服务不用考虑端口数量问题,监听某一个端口即可.但是向提供代理服务器,就不得不考虑端口数量受 ...
- Java版 家政服务 社区服务 家装服务平台 源码 有案例 可定制
产品说明: 家装服务平台.社区服务平台.服务类型的平台--公司成熟产品 包括工匠注册.资质认证.发布服务产品.会员注册.预约服务.工匠定价.执行服务.服务完毕填写工作日志上传现场照片.会员确认服务.返 ...
- JAVA的内存模型及结构
所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢? Java内存模型 Java内存模型在JVM ...
- [内核驱动] miniFilter 内核层与应用程序通信
转载:http://blog.csdn.net/heyabo/article/details/8721611 转载:http://www.cnblogs.com/ljinshuan/archive/2 ...