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)
 

  这道题刚开始时没有思路......后来发现好像和区间众数的方法有点像......

  好了,我们考虑如何做这道题。首先,我们可以把区间分块。然后,我们可以用$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 历史研究的更多相关文章

  1. BZOJ 4241: 历史研究——莫队 二叉堆

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4241 题意:N个int范围内的数,M次询问一个区间最大的(数字*出现次数)(加权众数),可以 ...

  2. BZOJ 4241: 历史研究 ( 回 滚 )

    题目:  链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4241 题意:给你一个长度为n序列,m次查询,每次询问 一段区间 最大的  a[ i ...

  3. bzoj 4241 历史研究——分块(区间加权众数)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4241 套路:可以大力预处理,如果求区间加权众数,可以预处理i~j块(或 j 位置)的最大值, ...

  4. BZOJ.4241.历史研究(回滚莫队 分块)

    题目链接 \(Description\) 长度为n的数列,m次询问,每次询问一段区间最大的 \(A_i*tm_i\) (重要度*出现次数) \(Solution\) 好像可以用莫队做,但是取max的操 ...

  5. BZOJ 4241 历史研究(分块)

    题意 题解 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> ...

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

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

  7. bzoj4241/AT1219 历史研究(回滚莫队)

    bzoj4241/AT1219 历史研究(回滚莫队) bzoj它爆炸了. luogu 题解时间 我怎么又在做水题. 就是区间带乘数权众数. 经典回滚莫队,一般对于延长区间简单而缩短区间难的莫队题可以考 ...

  8. BZOJ4241 历史研究

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

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

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

随机推荐

  1. iOS 更改webView文字颜色丶文字大小丶背景色的方法

    在webView的delegate回调方法    - (void)webViewDidFinishLoad:(UIWebView *)webView;中写上一下语句即可 //字体大小 [webView ...

  2. 网络热恋之json解析

    现在的app开发很少有用到XML解析的了,主流的则是JSON. // // ViewController.m // CX-JSON解析(三方JSONKit-master) #import " ...

  3. ios git 终端提交

    git status    //检查提交状态 git status On branch master  //检查分支 git branch   //查看分支 git add *   //添加所有本地更 ...

  4. php中的curl

    /** * 请求接口返回内容 * @param string $url [请求的URL地址] * @param string $params [请求的参数] * @param int $ipost [ ...

  5. Java 往年试卷参考答案!!!

    仅供参考: 第一题: E C E A D D C A C A C A B A B C C D B C 第二题: True True False 11 12 13 14 No such file fou ...

  6. jQuery添加options点击事件并传值

    说明: 根据选择不同店铺选项,上送不同id值,展示不同商品列表   var formStr = "{'supplierId':'供应链企业|%-jm-sprt-%|93794498-3'}& ...

  7. Java调用webservice接口方法

                             java调用webservice接口   webservice的 发布一般都是使用WSDL(web service descriptive langu ...

  8. CMPP错误码说明

    与中国移动代码的对应关系. MI::zzzzSMSC返回状态报告的状态值为EXPIREDMJ:zzzzSMSC返回状态报告的状态值为DELETEDMK:zzzzSMSC返回状态报告的状态值为UNDEL ...

  9. phpStydy配置memcache扩展

    一.下载并安装memcached服务器端软件    1.下载memcached软件 32位下载地址: memcached-win32-1.4.4-14.zip(直接下载),memcached-win3 ...

  10. 0008《SQL必知必会》笔记04-子查询、联接与组合查询

    1.子查询:就是嵌套的查询,用一个查询的结果作为另一个查询的条件. 比如要列出订购了物品“RGAN01”的所有顾客的ID.姓名和联系人,需要经历以下几步 (1)从orderitems中找出订购了“RG ...