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)

正解:分块

解题报告:

  这道题卡了我好久。。。数据恶心,差评。。。

  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了。常数害死人。。。

  

  1. //It is made by jump~
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <ctime>
  9. #include <vector>
  10. #include <queue>
  11. #include <map>
  12. #include <set>
  13. #ifdef WIN32
  14. #define OT "%I64d"
  15. #else
  16. #define OT "%lld"
  17. #endif
  18. using namespace std;
  19. typedef long long LL;
  20. const int MAXN = ;
  21. const int kk = ;
  22. int n,m;
  23. int belong[MAXN],L[MAXN],R[MAXN];
  24. int num[MAXN];
  25. int match[MAXN],Stack[MAXN],top;
  26. LL w[kk][kk];
  27. int cnt[kk][MAXN];//w[i][j]表示第i块到第j块的答案, cnt[i][j]表示前i块数字为j的个数
  28. LL ans;
  29.  
  30. struct node{
  31. int val,id;
  32. }a[MAXN];
  33.  
  34. inline int getint()
  35. {
  36. int w=,q=;
  37. char c=getchar();
  38. while((c<'' || c>'') && c!='-') c=getchar();
  39. if (c=='-') q=, c=getchar();
  40. while (c>='' && c<='') w=w*+c-'', c=getchar();
  41. return q ? -w : w;
  42. }
  43.  
  44. inline bool cmp(node q,node qq){ return q.val<qq.val; }
  45. inline LL max(LL x,LL y){ if(x<y) return y; return x; }
  46.  
  47. inline void work(){
  48. n=getint(); m=getint(); int block=sqrt(n),kuai;
  49. //int block=325; int kuai;
  50. kuai=(n-)/block+;
  51. for(int i=;i<=n;i++) a[i].val=getint(),a[i].id=i;
  52. for(int i=;i<=n;i++) {
  53. belong[i]=(i-)/block+;
  54. if(!L[belong[i]]) L[belong[i]]=i;
  55. R[belong[i]]=i;
  56. }
  57. sort(a+,a+n+,cmp); match[a[].id]=;
  58. //用每个数字出现的第一个位置代替这个数字作为它的编号
  59. for(int i=;i<=n;i++) {//构出从小到大的原来顺序的离散化结果
  60. if(a[i].val==a[i-].val) match[a[i].id]=match[a[i-].id];
  61. else match[a[i].id]=i;
  62. }
  63. for(int i=;i<=n;i++) cnt[belong[i]][match[i]]++;
  64. for(int i=;i<=kuai;i++) for(int j=;j<=n;j++) cnt[i][j]+=cnt[i-][j];//构前缀和
  65. for(int i=;i<=kuai;i++) {
  66. memset(num,,sizeof(num)); ans=;
  67. for(int now=L[i];now<=n;now++) {//按原先的顺序统计种类的个数
  68. num[match[now]]++; ans=max(ans,(LL)num[match[now]]*a[match[now]].val);
  69. if(now==R[belong[now]]) w[i][belong[now]]=ans;//已经到最后一个
  70. }
  71. }
  72. memset(num,,sizeof(num));
  73. int l,r;
  74. for(int o=;o<=m;o++) {
  75. l=getint(); r=getint(); ans=;
  76. if(belong[l]==belong[r]) {
  77. top=;
  78. 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); }
  79. //我们记录一个处理过的种类,Stack保存需要清零的对象
  80. while(top>) num[Stack[top--]]=;
  81. }
  82. else{
  83. top=; if(belong[l]<belong[r]) ans=w[belong[l]+][belong[r]-];
  84. //找到不完整的块中的出现的种类,然后统计完整的块中的出现的次数
  85. 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];
  86. 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];
  87. for(int i=l;i<=R[belong[l]];i++) num[match[i]]++;
  88. for(int i=L[belong[r]];i<=r;i++) num[match[i]]++;
  89. while(top>) { ans=max(ans,(LL)num[Stack[top]]*a[Stack[top]].val); num[Stack[top--]]=;}//清零
  90. }
  91. printf("%lld\n",ans);
  92. }
  93. }
  94.  
  95. int main()
  96. {
  97. work();
  98. return ;
  99. }

BZOJ4241 历史研究的更多相关文章

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

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

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

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

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

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

  4. BZOJ4241 历史研究 莫队 堆

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

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

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

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

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

  7. BZOJ4241 历史研究(莫队)

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

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

    传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...

  9. bzoj4241: 历史研究(回滚莫队)

    传送门 这是一个叫做回滚莫队的神奇玩意儿 是询问,而且不强制在线,就决定是你了莫队 如果是每次插入一个数是不是很简单? 然而悲剧的是我们莫队的时候不仅要插入数字还要删除数字 那么把它变成只插入不就行了 ...

随机推荐

  1. 第8课 goto 和 void 分析

    1. 遭人遗弃的goto (1)高手潜规则:禁用goto (2)项目经验:程序质量与goto出现的次数成反比 (3)最后的判决:将goto打入冷宫(1)循环语句的基本工作方式 [实例分析]goto副作 ...

  2. flex4 s:Datagrid <s:typicalItem

    <s:DataGird <s:typicalItem 这个标签相信大家很陌生吧, 我也是今天准备讲的时候才看到,估计是 flex4.5.1 新加东西,果然摸索 了下,这个标签作用也蛮好用的 ...

  3. eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能(同时解决自动补全变量名的问题)?

    对于编程人员来说,要记住大量的类名或类方法的名字,着实不是一件容易的事情.如果要IDE能够自动补全代码,那将为我们编程人员带来很大帮助. eclipse代码里面的代码提示功能默认是关闭的,只有输入“. ...

  4. Dvwa writeup

    DVWA(Dam vulnerable Web Application)是使用PHP+Mysql编写的一套用于常规漏洞教学和漏洞挖掘的一个测试学习程序,在此程序中包含了常见的web方面的漏洞,如命令行 ...

  5. RDP协议

    远程桌面协议 (RDP),用于终端服务器和终端服务器客户端之间的通信.RDP 被封装并在 TCP 加密. 远程桌面协议基于,并是对扩展 T 系列的协议标准. 多声道支持协议用于单独的虚拟通道储存的演示 ...

  6. Go Walk教程 - 流程控制( switch)

    Go的 switch 非常灵活,表达式不必是常量或整数,执行的过程从上至下,直到找到匹配项,不要break: var score =98 var result string switch score/ ...

  7. 突然想起android与mfc差异

    两者都可以算作是客户端程序,都是做上位机用的.而且都是被动执行. 相同点: 1.MFC中,它是由 project的名字 里面的某个成员函数来初始化,窗体,以及窗体里面的变量. 后面都是监听消息循环.数 ...

  8. oracle文字与格式字符串不匹配的解决

    oracle文字与格式字符串不匹配的解决 oracle的日期时间类型 在往oracle的date类型插入数据的时候,记得要用to_date()方法. 如insert into CUSLOGS(STAR ...

  9. EasyUI Tree判断节点是否是叶

    方法1:  $('#domaincatalog').tree('isLeaf', node.target); 返回true或false ,true表示是叶节点, false即不是 方法2:官方文档中: ...

  10. WCF4.0 –- RESTful WCF Services (1) (入门)

    WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构层面上的考虑. 因为它天生就具有很好的跨平台跨语言的集成能力,几乎所有的语言和网络平台都支持 HTTP 请求,无需去实现复 ...