BZOJ4241 历史研究
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
正解:分块
解题报告:
这道题卡了我好久。。。数据恶心,差评。。。
w[i][j]表示第i块到第j块的答案(即题目要求的最大值),cnt[i][j]表示前i块种类为j的数的个数前缀和。
显然这可以O(N^(3/2))预处理。查询的时候整块的直接以整块答案为初值,然后考虑“边角余料”,加进num中统计,更新答案,具体看代码吧。
我开始WA了,因为有一个数组没开long long。。。之后一直TLE,我不知道一个评测80s的题目TLE几次是什么感觉。。。经过二分查错,我发现并没有问题。
最后迷之AC了,因为把一个不必要的long long开成了int就AC了。常数害死人。。。
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = ;
const int kk = ;
int n,m;
int belong[MAXN],L[MAXN],R[MAXN];
int num[MAXN];
int match[MAXN],Stack[MAXN],top;
LL w[kk][kk];
int cnt[kk][MAXN];//w[i][j]表示第i块到第j块的答案, cnt[i][j]表示前i块数字为j的个数
LL ans; struct node{
int val,id;
}a[MAXN]; inline int getint()
{
int w=,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;
} inline bool cmp(node q,node qq){ return q.val<qq.val; }
inline LL max(LL x,LL y){ if(x<y) return y; return x; } inline void work(){
n=getint(); m=getint(); int block=sqrt(n),kuai;
//int block=325; int kuai;
kuai=(n-)/block+;
for(int i=;i<=n;i++) a[i].val=getint(),a[i].id=i;
for(int i=;i<=n;i++) {
belong[i]=(i-)/block+;
if(!L[belong[i]]) L[belong[i]]=i;
R[belong[i]]=i;
}
sort(a+,a+n+,cmp); match[a[].id]=;
//用每个数字出现的第一个位置代替这个数字作为它的编号
for(int i=;i<=n;i++) {//构出从小到大的原来顺序的离散化结果
if(a[i].val==a[i-].val) match[a[i].id]=match[a[i-].id];
else match[a[i].id]=i;
}
for(int i=;i<=n;i++) cnt[belong[i]][match[i]]++;
for(int i=;i<=kuai;i++) for(int j=;j<=n;j++) cnt[i][j]+=cnt[i-][j];//构前缀和
for(int i=;i<=kuai;i++) {
memset(num,,sizeof(num)); ans=;
for(int now=L[i];now<=n;now++) {//按原先的顺序统计种类的个数
num[match[now]]++; ans=max(ans,(LL)num[match[now]]*a[match[now]].val);
if(now==R[belong[now]]) w[i][belong[now]]=ans;//已经到最后一个
}
}
memset(num,,sizeof(num));
int l,r;
for(int o=;o<=m;o++) {
l=getint(); r=getint(); ans=;
if(belong[l]==belong[r]) {
top=;
for(int i=l;i<=r;i++) { if(!num[match[i]]) Stack[++top]=match[i]; num[match[i]]++; ans=max(ans,(LL)num[match[i]]*a[match[i]].val); }
//我们记录一个处理过的种类,Stack保存需要清零的对象
while(top>) num[Stack[top--]]=;
}
else{
top=; if(belong[l]<belong[r]) ans=w[belong[l]+][belong[r]-];
//找到不完整的块中的出现的种类,然后统计完整的块中的出现的次数
for(int i=l;i<=R[belong[l]];i++) if(!num[match[i]]) num[match[i]]=cnt[belong[r]-][match[i]]-cnt[belong[l]][match[i]],Stack[++top]=match[i];
for(int i=L[belong[r]];i<=r;i++) if(!num[match[i]]) num[match[i]]=cnt[belong[r]-][match[i]]-cnt[belong[l]][match[i]],Stack[++top]=match[i];
for(int i=l;i<=R[belong[l]];i++) num[match[i]]++;
for(int i=L[belong[r]];i<=r;i++) num[match[i]]++;
while(top>) { ans=max(ans,(LL)num[Stack[top]]*a[Stack[top]].val); num[Stack[top--]]=;}//清零
}
printf("%lld\n",ans);
}
} int main()
{
work();
return ;
}
BZOJ4241 历史研究的更多相关文章
- [JOISC2014]歴史の研究/[BZOJ4241]历史研究
[JOISC2014]歴史の研究/[BZOJ4241]历史研究 题目大意: 一个长度为\(n(n\le10^5)\)的数列\(A(A_i\le10^9)\),定义一个元素对一个区间\([l,r]\)的 ...
- 【题解】BZOJ4241: 历史研究(魔改莫队)
[题解]BZOJ4241: 历史研究(魔改莫队) 真的是好题啊 题意 给你一个序列和很多组询问(可以离线),问你这个区间中\(\max\){元素出现个数\(\times\)元素权值} 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: 历史研究(回滚莫队)
传送门 这是一个叫做回滚莫队的神奇玩意儿 是询问,而且不强制在线,就决定是你了莫队 如果是每次插入一个数是不是很简单? 然而悲剧的是我们莫队的时候不仅要插入数字还要删除数字 那么把它变成只插入不就行了 ...
随机推荐
- jsp 微信公众平台 token验证(php、jsp)(转载)
微信公众平台现在推出自动回复消息接口,但是由于是接口内容用的是PHP语言写的,很多地方操作起来让本人这个对java比较熟悉的小伙很别扭,所以仿照PHP的接口代码做了一套jsp语言编写的接口. 首先先把 ...
- Genymotion出现unknown generic error和This may occur if you are using a proxy错误的解决方案
今天在实验室希望在Genymotion上多下载几个模拟器,需要重新登录帐号,却发现一个错误,叫做unknown generic error.前几天还出现过一个很诡异的问题.截图如下: . (1)unk ...
- Android优化—— 内存分析工具 MAT 的使用
1 内存泄漏的排查方法 Dalvik Debug Monitor Server (DDMS) 是 ADT插件的一部分,其中有两项功能可用于内存检查 : · heap 查看堆的分配情况 · ...
- Android优化——UI优化(三)使用ViewStub延迟加载
使用ViewStub延迟加载 1.ViewStub延迟加载 ViewStub是一个不可见的,大小为0的View,最佳用途就是实现View的延迟加载,在需要的时候再加载View,可Java中常见的性能优 ...
- ABP入门系列(5)——创建应用服务
一.解释下应用服务层 应用服务用于将领域(业务)逻辑暴露给展现层.展现层通过传入DTO(数据传输对象)参数来调用应用服务,而应用服务通过领域对象来执行相应的业务逻辑并且将DTO返回给展现层.因此,展现 ...
- git review报错一例
在线上修改代码,最后使用git review提交代码审核的时候出现报错如下:[wangshibo@115~]$ vim testfile #修改代码[wangshibo@115~] ...
- 【转】【WPF】WPF 登录窗口关闭时打开主窗口
在WPF中设计登录窗口关闭时打开主窗口,自动生成的App.xaml不能满足要求, 1.把App.xaml的属性窗口中的生成操作设定为 无 2.添加Program类 static class Progr ...
- 域策略禁用usb
文档及模板可在 http://pan.baidu.com/s/1qYTcjTy 下载 pro_usb_users.adm 此模板可禁用到 指定盘符,针对用户策略 pro_usb_computers ...
- Linux 网络编程五(UDP协议)
UDP和TCP的对比 --UDP处理的细节比TCP少. --UDP不能保证消息被传送到目的地. --UDP不能保证数据包的传递顺序. --TCP处理UDP不处理的细节. --TCP是面向连接的协议 - ...
- 广州传智博客黑马训练营.Net15期
广州传智博客黑马训练营.Net15期 7 张扬波 MVC大项目 6 张扬波 MVC 3 胡凌浩 HTML&JS 2 基础加强+三层 5 张扬波 企业站点(asp.net)&EF 4 江 ...