BZOJ 4241 历史研究
Description
Input
Output
Sample Input
9 8 7 8 9
1 2
3 4
4 4
1 4
2 4
Sample Output
8
8
16
16
HINT
这道题刚开始时没有思路......后来发现好像和区间众数的方法有点像......
好了,我们考虑如何做这道题。首先,我们可以把区间分块。然后,我们可以用$O(n \sqrt{n})$的复杂度求出$f_{i,j}$,表示取第$i$块到第$j$块中所有元素的答案。
然后,我们考虑如何得到区间$[l,r]$的答案。如果$l$和$r$在同一块,那么显然扫一遍这个块就可以了。否则,我们可以先把$[l,r]$覆盖的完整的块的答案统计一下,再统计一下边角余料中答案最大的数。显然答案一定在这三者中。
但是,统计边角余料的答案并不好做。于是,我们可以再来一个数组$cnt_{i,j}$,表示前$i$个块中第$j$号元素出现了多少次(注意先要离散化),然后我们就可以$O(1)$地统计完整的块中每种元素出现的个数了。取一下$\max$就可以了。
下面是代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 100010
#define kuai 501 using namespace std;
typedef long long llg; int n,m,N,ln,L[kuai],R[kuai],cnt[kuai][maxn];
int a[maxn],b[maxn],lb,c[maxn],ci[maxn],be[maxn];
llg f[kuai][kuai],ans; int getint(){
int w=;bool q=;
char c=getchar();
while((c>''||c<'')&&c!='-') c=getchar();
if(c=='-') q=,c=getchar();
while(c>=''&&c<='') w=w*+c-'',c=getchar();
return q?-w:w;
} int main(){
n=getint();m=getint();
for(int i=;i<=n;i++) a[i]=b[i]=getint();
sort(b+,b+n+); lb=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++){
int l=,r=lb,mid;
while(l!=r){
mid=l+r>>;
if(a[i]<=b[mid]) r=mid;
else l=mid+;
}
c[i]=l;
}
N=sqrt(n); ln=n/N; if(n%N) ln++;
for(int i=;i<ln;i++) L[i]=R[i-]+,R[i]=N*i;
L[ln]=R[ln-]+; R[ln]=n;
for(int i=,r;i<=ln;i++){
ans=; r=L[i]-;
for(int j=L[i];j<=R[i];j++) cnt[i][c[j]]++,be[j]=i;
for(int j=;j<=ln;j++){
while(r<R[j]){
r++; ci[c[r]]++;
ans=max(ans,(llg)(ci[c[r]])*(llg)a[r]);
}
f[i][j]=ans;
}
for(int j=;j<=n;j++) cnt[i][j]+=cnt[i-][j];
for(int j=;j<=lb;j++) ci[j]=;
}
while(m--){
int l=getint(),r=getint(); ans=;
if(be[l]==be[r]){
for(int i=l;i<=r;i++)
ans=max(ans,(llg)(++ci[c[i]])*(llg)a[i]);
for(int i=l;i<=r;i++) ci[c[i]]--;
}
else{
ans=f[be[l]+][be[r]-];
for(int i=l;i<=R[be[l]];i++)
ans=max(ans,(llg)((++ci[c[i]])+cnt[be[r]-][c[i]]-cnt[be[l]][c[i]])*(llg)a[i]);
for(int i=L[be[r]];i<=r;i++)
ans=max(ans,(llg)((++ci[c[i]])+cnt[be[r]-][c[i]]-cnt[be[l]][c[i]])*(llg)a[i]);
for(int i=l;i<=R[be[l]];i++) ci[c[i]]--;
for(int i=L[be[r]];i<=r;i++) ci[c[i]]--;
}
printf("%lld\n",ans);
}
return ;
}
BZOJ 4241 历史研究的更多相关文章
- BZOJ 4241: 历史研究——莫队 二叉堆
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4241 题意:N个int范围内的数,M次询问一个区间最大的(数字*出现次数)(加权众数),可以 ...
- BZOJ 4241: 历史研究 ( 回 滚 )
题目: 链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4241 题意:给你一个长度为n序列,m次查询,每次询问 一段区间 最大的 a[ i ...
- bzoj 4241 历史研究——分块(区间加权众数)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4241 套路:可以大力预处理,如果求区间加权众数,可以预处理i~j块(或 j 位置)的最大值, ...
- BZOJ.4241.历史研究(回滚莫队 分块)
题目链接 \(Description\) 长度为n的数列,m次询问,每次询问一段区间最大的 \(A_i*tm_i\) (重要度*出现次数) \(Solution\) 好像可以用莫队做,但是取max的操 ...
- BZOJ 4241 历史研究(分块)
题意 题解 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> ...
- 【题解】BZOJ4241: 历史研究(魔改莫队)
[题解]BZOJ4241: 历史研究(魔改莫队) 真的是好题啊 题意 给你一个序列和很多组询问(可以离线),问你这个区间中\(\max\){元素出现个数\(\times\)元素权值} IOI国历史研究 ...
- bzoj4241/AT1219 历史研究(回滚莫队)
bzoj4241/AT1219 历史研究(回滚莫队) bzoj它爆炸了. luogu 题解时间 我怎么又在做水题. 就是区间带乘数权众数. 经典回滚莫队,一般对于延长区间简单而缩短区间难的莫队题可以考 ...
- BZOJ4241 历史研究
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
- BZOJ4241历史研究——回滚莫队
题目描述 IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. 日记中记录了连 ...
随机推荐
- Hibernate连接mysql数据库并自动创建表
天才第一步,雀氏纸尿裤,Hibernate第一步,连接数据库. Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个 ...
- 世道变了 – 你愿意成为微软认证Linux工程师吗?
随笔世道变了 – 你愿意成为微软认证Linux工程师吗? 世道变了 – 你愿意成为微软认证Linux工程师吗? leixu十二月 14, 2015随笔 2015年12月9日,微软发布了全新的MCS ...
- Asp.net MVC Razor模板引擎技巧分享
Razor是Asp.net MVC中新的默认模板类型, 语法简单易用.这篇文章不涉及Razor的语法,主要介绍Razor的一些在MVC项目中的使用技巧,以及脱离MVC环境下,如何使用Razor. 阅读 ...
- Java集合分组
public class Data { private Long id ; private Long courseId ; private String content ; public Long g ...
- java的finalize()函数
在说明finalize()的用法之前要树立有关于java垃圾回收器几个观点: "对象可以不被垃圾回收" : java的垃圾回收遵循一个特点, 就是能不回收就不会回收.只要程序的内存 ...
- Web环境使用相对路径发布Webservice
常我们的Webservice服务的发布地址都将是一个相对路径,在与Spring一起使用时我们需要引入Cxf配置Webservice的schema,如jaxws,用以定义对应的Webservice. & ...
- MVC Ajax Helper或jQuery异步方式加载部分视图
Model: namespace MvcApplication1.Models { public class Team { public string Preletter { get; set; } ...
- python基础(一)
简单的‘Hello World!’ Python命令行 假设你已经安装好了Python, 那么在Linux命令行输入: $python 将直接进入python.然后在命令行提示符>>> ...
- Linux磁盘管理之创建磁盘分区05
一.磁盘基础知识 磁盘安装在计算机上后,在系统读取到硬盘后并不能直接使用,必须经过分区.格式化才能够正确使用.这一次主要是针对磁盘分区进行简单总结,存储设备类型:U盘.光盘.软盘.硬盘.磁带. 硬盘接 ...
- 使用bakefile编译C工程代码
前言 最近有个想法,想把ineedle整体架构从头自己编写代码来实现一下,来加深对iNeedle系统的理解,同时加强Linux + C相关知识.由于iNeedle系统的庞大,只能是先把框架搭起来,根据 ...