[JOISC2014]歴史の研究/[BZOJ4241]历史研究
[JOISC2014]歴史の研究/[BZOJ4241]历史研究
题目大意:
一个长度为\(n(n\le10^5)\)的数列\(A(A_i\le10^9)\),定义一个元素对一个区间\([l,r]\)的贡献为\(A_i\times cnt(A_i)\),其中\(cnt(A_i)\)表示\(A_i\)在区间内的出现次数。\(q(q\le10^5)\)次询问,每次询问一个区间内贡献最大的元素的贡献。
思路:
分块。
\(cnt[i][j]\)表示前\(i\)块内\(j\)的出现次数,\(sum[i][j]\)表示\([begin(i),end(j)]\)的答案。
对\(A\)离散化后预处理\(cnt\)和\(sum\),询问时如果\(l,r\)在同一块直接暴力。如果不在同一块,则答案要么是\(sum[bel(l)+1,bel(r)-1]\),要么是\(l,r\)所在块中出现过的元素的贡献。
时间复杂度\(\mathcal O(n^{\frac32})\)。
源代码:
#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=1e5,M=317;
int n,m,q,block,a[N],b[N],bel[N],begin[M],end[M],tmp[N],cnt[M][N];
int64 sum[M][M];
inline int64 query(const int &l,const int &r) {
int64 ret=0;
if(bel[l]==bel[r]) {
for(register int i=l;i<=r;i++) {
tmp[a[i]]++;
ret=std::max(ret,(int64)b[a[i]]*tmp[a[i]]);
}
for(register int i=l;i<=r;i++) tmp[a[i]]--;
return ret;
}
ret=sum[bel[l]+1][bel[r]-1];
for(register int i=l;i<=end[bel[l]];i++) {
tmp[a[i]]++;
ret=std::max(ret,(int64)b[a[i]]*(tmp[a[i]]+cnt[bel[r]-1][a[i]]-cnt[bel[l]][a[i]]));
}
for(register int i=begin[bel[r]];i<=r;i++) {
tmp[a[i]]++;
ret=std::max(ret,(int64)b[a[i]]*(tmp[a[i]]+cnt[bel[r]-1][a[i]]-cnt[bel[l]][a[i]]));
}
for(register int i=l;i<=end[bel[l]];i++) tmp[a[i]]--;
for(register int i=begin[bel[r]];i<=r;i++) tmp[a[i]]--;
return ret;
}
int main() {
n=getint(),q=getint(),block=sqrt(n);
for(register int i=0;i<n;i++) {
a[i]=b[i]=getint();
bel[i]=i/block;
end[bel[i]]=i;
}
for(register int i=n-1;i>=0;i--) {
begin[bel[i]]=i;
}
std::sort(&b[0],&b[n]);
m=std::unique(&b[0],&b[n])-b;
for(register int i=0;i<n;i++) {
a[i]=std::lower_bound(&b[0],&b[m],a[i])-b;
cnt[bel[i]][a[i]]++;
}
for(register int i=1;i<=bel[n-1];i++) {
for(register int j=0;j<m;j++) {
cnt[i][j]+=cnt[i-1][j];
}
}
for(register int i=0;i<=bel[n-1];i++) {
for(register int j=begin[i];j<=end[i];j++) {
tmp[a[j]]++;
sum[i][i]=std::max(sum[i][i],(int64)b[a[j]]*tmp[a[j]]);
}
for(register int j=begin[i];j<=end[i];j++) tmp[a[j]]--;
for(register int j=i+1;j<=bel[n-1];j++) {
sum[i][j]=sum[i][j-1];
for(register int k=begin[j];k<=end[j];k++) {
tmp[a[k]]++;
sum[i][j]=std::max(sum[i][j],(int64)b[a[k]]*(tmp[a[k]]+cnt[j-1][a[k]]-(i!=0?cnt[i-1][a[k]]:0)));
}
for(register int k=begin[j];k<=end[j];k++) tmp[a[k]]--;
}
}
for(register int i=0;i<q;i++) {
const int l=getint()-1,r=getint()-1;
printf("%lld\n",query(l,r));
}
return 0;
}
[JOISC2014]歴史の研究/[BZOJ4241]历史研究的更多相关文章
- 【题解】BZOJ4241: 历史研究(魔改莫队)
[题解]BZOJ4241: 历史研究(魔改莫队) 真的是好题啊 题意 给你一个序列和很多组询问(可以离线),问你这个区间中\(\max\){元素出现个数\(\times\)元素权值} 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国的生活,开始着手调查日记中记载的事件. ...
- [bzoj4241][历史研究] (分块)
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
- BZOJ4241 历史研究(莫队)
如果分块的话与区间众数没有本质区别.这里考虑莫队. 显然莫队时的删除可以用堆维护,但多了一个log不太跑得过. 有一种叫回滚莫队的trick,可以将问题变为只有加入操作.按莫队时分的块依次处理,一块中 ...
- 2018.08.14 bzoj4241: 历史研究(回滚莫队)
传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...
- bzoj4241: 历史研究(回滚莫队)
传送门 这是一个叫做回滚莫队的神奇玩意儿 是询问,而且不强制在线,就决定是你了莫队 如果是每次插入一个数是不是很简单? 然而悲剧的是我们莫队的时候不仅要插入数字还要删除数字 那么把它变成只插入不就行了 ...
随机推荐
- nginx配置浅析
一.nginx的介绍 nginx是由俄罗斯人开发的一款高性能的http和反向代理服务器,也可以用来作为邮件代理.相比较于其他的服务器,具有占用内存少,稳定性高等优势 二.nginx的配置 nginx的 ...
- WCF ServiceContract,OperationContract
代码如下 [ServiceContract] //服务协定定义 using System.ServiceModel; public interface IInterface1 { [Operation ...
- Flask:静态文件&模板(0.1)
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 前面看了Flask的Quickstart文档,可是,一直没有练习里面的内容,这不,刚刚练习完毕,来写篇博文记录一下! ...
- 用js面向对象思想封装插件
js是基于原型的面向对象语言,如果你学过java,c#等正统面向对象语言,你会难以理解js的面向对象,他和普通的面向对象不太一样,今天,我们通过封装一个toast插件,来看看js面向对象是如何运行的. ...
- Codeforces 801C Voltage Keepsake(二分枚举+浮点(模板))
题目链接:http://codeforces.com/contest/801/problem/C 题目大意:给你一些电器以及他们的功率,还有一个功率一定的充电器可以给这些电器中的任意一个充电,并且不计 ...
- Java多线程-Java多线程概述
第一章 Java多线程概述 线程的启动 线程的暂停 线程的优先级 线程安全相关问题 1.1 进程与线程 进程:可以将运行在内存中的程序(如exe文件)理解为进程,进程是受操作系统管理的基本的运行单元. ...
- LeetCode403. Frog Jump
A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...
- 基于docker 搭建Prometheus+Grafana
一.介绍Prometheus Prometheus(普罗米修斯)是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的.随着发展,越来越多公司和组织接受采 ...
- WeifenLuo.WinFormsUI.Docking"的使用
要用 WeifenLuo.WinFormsUI.Docking 首先要下载: WeifenLuo.WinFormsUI.Docking 在当前工程“解决方案 - 引用”中 >> 右击引用 ...
- 防止一个exe被打开多次
mutex有一个名字,如果这个exe已经打开了,createNew返回的就是false,程序就退出了. 这是个wpf application的例子 protected override void On ...