【BZOJ4241】历史研究

Description

IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记。JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件。
日记中记录了连续N天发生的时间,大约每天发生一件。
事件有种类之分。第i天(1<=i<=N)发生的事件的种类用一个整数Xi表示,Xi越大,事件的规模就越大。
JOI教授决定用如下的方法分析这些日记:
1. 选择日记中连续的一些天作为分析的时间段
2. 事件种类t的重要度为t*(这段时间内重要度为t的事件数)
3. 计算出所有事件种类的重要度,输出其中的最大值
现在你被要求制作一个帮助教授分析的程序,每次给出分析的区间,你需要输出重要度的最大值。

Input

第一行两个空格分隔的整数N和Q,表示日记一共记录了N天,询问有Q次。
接下来一行N个空格分隔的整数X1...XN,Xi表示第i天发生的事件的种类
接下来Q行,第i行(1<=i<=Q)有两个空格分隔整数Ai和Bi,表示第i次询问的区间为[Ai,Bi]。

Output

输出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

Sample Output

9
8
8
16
16

HINT

1<=N<=10^5
1<=Q<=10^5
1<=Xi<=10^9 (1<=i<=N)

题解:第一眼看题都感觉是莫队吧?然而听说这题卡莫队。

这题的本质是一个带权的区间众数问题,如果你会做区间众数,那么这道题也不难(当然不会做也无所谓)。

先分块,假设[a,b]是[l,r]中一段连续的整块,那么[l,r]中的带权众数∈([a,b]中的众数 U [l,a)和(b,r]中的所有数)。那么我们预处理出任意两个块(a,b)之间的带权众数(方法:枚举左边的块,在暴力扫一遍右边的所有块,用桶记录一下,维护个最大值),以及[1,a]中所有数出现的次数。处理询问时,先直接拿出中间整块的众数,再枚举两边小块的所有数即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,m,nm,B;
ll ans;
struct node
{
int val,org;
}num[maxn];
int v[maxn],ref[maxn],st[maxn],s[400][maxn];
ll mx[400][400];
bool cmp(node a,node b)
{
return a.val<b.val;
}
int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
int main()
{
n=rd(),m=rd();
B=int(sqrt(double(n)));
int i,j,k,a,b,c,d;
for(i=0;i<n;i++) num[i].val=rd(),num[i].org=i;
sort(num,num+n,cmp);
for(ref[0]=-1,i=0;i<n;i++)
{
if(num[i].val>ref[nm]) ref[++nm]=num[i].val;
v[num[i].org]=nm;
}
for(i=0;i<n;i++) s[i/B][v[i]]++;
for(i=1;i*B<n;i++) for(j=1;j<=nm;j++) s[i][j]+=s[i-1][j];
for(i=0;i*B<n;i++)
{
for(j=i;j*B<n;j++)
{
mx[i][j]=mx[i][j-1];
for(k=j*B;k<j*B+B&&k<n;k++) st[v[k]]++,mx[i][j]=max(mx[i][j],(ll)st[v[k]]*ref[v[k]]);
}
memset(st,0,sizeof(st));
}
for(i=1;i<=m;i++)
{
a=rd()-1,b=rd()-1,c=a/B,d=b/B,ans=0;
if(c==d)
{
for(j=a;j<=b;j++) st[v[j]]++,ans=max(ans,(ll)st[v[j]]*ref[v[j]]);
for(j=a;j<=b;j++) st[v[j]]=0;
printf("%lld\n",ans);
continue;
}
ans=mx[c+1][d-1];
for(j=a;j<c*B+B;j++) st[v[j]]=s[d-1][v[j]]-s[c][v[j]];
for(j=d*B;j<=b;j++) st[v[j]]=s[d-1][v[j]]-s[c][v[j]];
for(j=a;j<c*B+B;j++) st[v[j]]++,ans=max(ans,(ll)st[v[j]]*ref[v[j]]);
for(j=d*B;j<=b;j++) st[v[j]]++,ans=max(ans,(ll)st[v[j]]*ref[v[j]]);
for(j=a;j<c*B+B;j++) st[v[j]]=0;
for(j=d*B;j<=b;j++) st[v[j]]=0;
printf("%lld\n",ans);
}
return 0;
}

【BZOJ4241】历史研究 分块的更多相关文章

  1. [bzoj4241][历史研究] (分块)

    Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...

  2. bzoj4241 历史研究——分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4241 就是分块,预处理出从第 i 块到 j 位置的答案,以及从第 i 块到最后位置间每个数出 ...

  3. [JOISC2014]歴史の研究/[BZOJ4241]历史研究

    [JOISC2014]歴史の研究/[BZOJ4241]历史研究 题目大意: 一个长度为\(n(n\le10^5)\)的数列\(A(A_i\le10^9)\),定义一个元素对一个区间\([l,r]\)的 ...

  4. 【题解】BZOJ4241: 历史研究(魔改莫队)

    [题解]BZOJ4241: 历史研究(魔改莫队) 真的是好题啊 题意 给你一个序列和很多组询问(可以离线),问你这个区间中\(\max\){元素出现个数\(\times\)元素权值} IOI国历史研究 ...

  5. BZOJ4241 历史研究

    Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...

  6. BZOJ4241 历史研究 莫队 堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目 Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JO ...

  7. BZOJ4241历史研究——回滚莫队

    题目描述 IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. 日记中记录了连 ...

  8. BZOJ4241:历史研究(回滚莫队)

    Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...

  9. BZOJ4241 历史研究(莫队)

    如果分块的话与区间众数没有本质区别.这里考虑莫队. 显然莫队时的删除可以用堆维护,但多了一个log不太跑得过. 有一种叫回滚莫队的trick,可以将问题变为只有加入操作.按莫队时分的块依次处理,一块中 ...

随机推荐

  1. 如何证明一个数的数根(digital root)就是它对9的余数?

    数根就是不断地求这个数的各位数之和,直到求到个位数为止.所以数根一定和该数模9同余,但是数根又是大于零小于10的,所以数根模9的余数就是它本身,也就是说该数模9之后余数就是数根. 证明: 假设有一个n ...

  2. svn报“Previous operation has not finished; run 'cleanup' if it was interrupted”的错误

    -.叙述 今天需要更新接口文檔,所以就update了一下,結果報了如下錯誤:      Error : Previous operation has not finished; run 'cleanu ...

  3. Filter解决中文乱码问题

    1,FIlter中编码设置 编码设置一定要在跳转页面之前 public void doFilter(ServletRequest request, ServletResponse response, ...

  4. html5扫面二维码逻辑

    写在前面 项目中有这样的需求,在android端嵌入的html5应用中,需要扫描二维码,而一般的浏览器是不允许你调用摄像头的.最后时限方式是由app的webview进行扫描,将扫描结果返回,也就是js ...

  5. 一张图,关于 Bayes error rate,贝叶斯错误率等的分析

    造轮子是那帮搞研究的“科学家”干的事情(类似E&E里的explore),“工程师”的职责是利用已有的东西解决问题(类似E&E里的exploit). 其次,即使以工程师的角色解决业务问题 ...

  6. 传输层:TCP 协议

    传输层:TCP 协议 一.概述 TCP 和 UDP 处在同一层——运输层,但是它们有很多的不同.TCP 是 TCP/IP 系列协议中最复杂的部分,它具有以下特点: (1) TCP 提供 可靠的 数据传 ...

  7. (转)python装饰器二

    Python装饰器进阶之二 保存被装饰方法的元数据 什么是方法的元数据 举个栗子 def hello(): print('Hello, World.') print(dir(hello)) 结果如下: ...

  8. GIS可视化——属性图

    一.简介 SuperMap iClient for JavaScript 提供了UTFGrid图层(属性图),用于客户端属性信息的快速交互. UTFGrid图层从UTFGrid切片数据源读取数据,其本 ...

  9. java中的占位符\t\n\r\f

    \t 相当于tab,缩进\n NewLine 换行 System.out.println("aaa\tbbb"); //aaa bbbSystem.out.println(&quo ...

  10. sprinvmvc整合swagger实现实时接口信息展示

    1.pom.xml引入swagger插件 <dependency> <groupId>io.springfox</groupId> <artifactId&g ...