【题目链接】

https://www.lydsy.com/JudgeOnline/problem.php?id=2724

【算法】

分块算法在线维护区间众数

分块算法的精髓就在于 : 大段维护,局部朴素

这一题,我们可以将序列分成T段,那么每一段的长度就是(N/T)

对于每个询问,设l处于第p段,r处于第q段,那么 :

若p = q,用朴素算法计算出区间众数即可

否则,将这个序列分为三段 :

1.[L,R[p]] 2. [L[p+1],R[q-1]] 3. [L[q],r]

显然,区间众数只可能是 [L[p+1],R[q-1]]中的众数或[L,R[p]]中的一个数,或[L[q],r]中的一个数

不妨预处理所有以“段边界”为端点每个数出现的次数和区间众数

    当T取sqrt3(N)(开三次方)时,时间复杂度是非常优秀的 : O(n^(5/3))

【代码】

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define MAXN 40010
  4. const int INF = 2e9;
  5.  
  6. int i,j,k,n,m,l,r,l0,r0,lastans,t,block,len;
  7. int a[MAXN],val[MAXN],L[],R[],pos[MAXN],rk[MAXN];
  8. int cnt[][][MAXN],mx[][],d[][];
  9.  
  10. inline int query(int l,int r)
  11. {
  12. int i;
  13. static int sum[MAXN];
  14. int mx = ,ret = ;
  15. int p = pos[l],q = pos[r];
  16. if (p == q)
  17. {
  18. for (i = l; i <= r; i++)
  19. {
  20. sum[rk[i]]++;
  21. if (sum[rk[i]] > mx || (sum[rk[i]] == mx && rk[i] < ret))
  22. {
  23. mx = sum[rk[i]];
  24. ret = rk[i];
  25. }
  26. }
  27. for (i = l; i <= r; i++) sum[rk[i]]--;
  28. return ret;
  29. } else
  30. {
  31. ret = d[p+][q-];
  32. mx = cnt[p+][q-][ret];
  33. for (i = l; i <= R[p]; i++)
  34. {
  35. cnt[p+][q-][rk[i]]++;
  36. if (cnt[p+][q-][rk[i]] > mx || (cnt[p+][q-][rk[i]] == mx && rk[i] < ret))
  37. {
  38. mx = cnt[p+][q-][rk[i]];
  39. ret = rk[i];
  40. }
  41. }
  42. for (i = L[q]; i <= r; i++)
  43. {
  44. cnt[p+][q-][rk[i]]++;
  45. if (cnt[p+][q-][rk[i]] > mx || (cnt[p+][q-][rk[i]] == mx && rk[i] < ret))
  46. {
  47. mx = cnt[p+][q-][rk[i]];
  48. ret = rk[i];
  49. }
  50. }
  51. for (i = l; i <= R[p]; i++) cnt[p+][q-][rk[i]]--;
  52. for (i = L[q]; i <= r; i++) cnt[p+][q-][rk[i]]--;
  53. return ret;
  54. }
  55. }
  56.  
  57. int main()
  58. {
  59.  
  60. scanf("%d%d",&n,&m);
  61. for (i = ; i <= n; i++)
  62. {
  63. scanf("%d",&a[i]);
  64. val[++len] = a[i];
  65. }
  66. sort(val+,val+len+);
  67. len = unique(val+,val+len+) - val - ;
  68. for (i = ; i <= n; i++) rk[i] = lower_bound(val+,val+len+,a[i]) - val;
  69. block = (int)pow(n*1.0,1.0/);
  70. if (block) t = n / block;
  71. for (i = ; i <= block; i++)
  72. {
  73. L[i] = (i - ) * t + ;
  74. R[i] = i * t;
  75. }
  76. if (R[block] < n)
  77. {
  78. block++;
  79. L[block] = R[block-] + ;
  80. R[block] = n;
  81. }
  82. for (i = ; i <= block; i++)
  83. {
  84. for (j = L[i]; j <= R[i]; j++)
  85. {
  86. pos[j] = i;
  87. }
  88. }
  89. for (i = ; i <= block; i++)
  90. {
  91. for (j = i; j <= block; j++)
  92. {
  93. for (k = L[i]; k <= R[j]; k++)
  94. cnt[i][j][rk[k]]++;
  95. for (k = ; k <= len; k++)
  96. {
  97. if (cnt[i][j][k] > mx[i][j] || (cnt[i][j][k] == mx[i][j] && k < d[i][j]))
  98. {
  99. mx[i][j] = cnt[i][j][k];
  100. d[i][j] = k;
  101. }
  102. }
  103. }
  104. }
  105. lastans = ;
  106. for (i = ; i <= m; i++)
  107. {
  108. scanf("%d%d",&l0,&r0);
  109. l = (l0 + lastans - ) % n + ;
  110. r = (r0 + lastans - ) % n + ;
  111. if (l > r) swap(l,r);
  112. printf("%d\n",lastans = val[query(l,r)]);
  113. }
  114.  
  115. return ;
  116.  
  117. }

【BZOJ 2724】 蒲公英的更多相关文章

  1. bzoj 2724 蒲公英 分块

    分块,预处理出每两个块范围内的众数,然后在暴力枚举块外的进行比较 那么怎么知道每一个数出现的次数呢?离散后,对于每一个数,维护一个动态数组就好了 #include<cstdio> #inc ...

  2. BZOJ 2724 蒲公英 | 分块模板题

    题意 给出一个序列,在线询问区间众数.如果众数有多个,输出最小的那个. 题解 这是一道分块模板题. 一个询问的区间的众数,可能是中间"整块"区间的众数,也可能是左右两侧零散的数中的 ...

  3. BZOJ 2724蒲公英 (分块) 【内有块大小证明】

    题面 luogu传送门 分析 先分块,设块大小为x(之后我们会证明块大小取何值会更优) 步骤1 把所有的数离散化,然后对每个值开一个vector pos[i],pos[i]存储数i出现的位置 我们设查 ...

  4. [BZOJ 2724] [Violet 6] 蒲公英 【分块】

    题目链接:BZOJ - 2724 题目分析 这道题和 BZOJ-2821 作诗 那道题几乎是一样的,就是直接分块,每块大小 sqrt(n) ,然后将数字按照数值为第一关键字,位置为第二关键字排序,方便 ...

  5. BZOJ 2724: [Violet 6]蒲公英

    2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1633  Solved: 563[Submit][Status ...

  6. BZOJ 2724: [Violet 6]蒲公英( 分块 )

    虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...

  7. 【BZOJ 2724】 2724: [Violet 6]蒲公英 (区间众数不带修改版本)

    2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1908  Solved: 678 Description In ...

  8. 【刷题】BZOJ 2724 [Violet 6]蒲公英

    Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 Output Sample Input ...

  9. BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]

    传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...

随机推荐

  1. First step in troubleshooting complex issues: Define and scope your issue properly

    最近在查调试相关资料的时候,无意看到Tess的一篇关于如何快速分析复合场景问题的博文,感觉很实用,Mark备忘. My 9 questions for a pretty thorough proble ...

  2. 关于FastIo

    由于你的驱动将要绑定到文件系统驱动的上边,文件系统除了处理正常的IRP 之外,还要处理所谓的FastIo.FastIo是Cache Manager 调用所引发的一种没有irp 的请求.换句话说,除了正 ...

  3. [Offer收割]编程练习赛42

    对局匹配 直接贪心 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #i ...

  4. Android 自定义控件之圆形扩散View(DiffuseView)

    实现效果 使用 属性方法 代码 源码下载 参考链接 实现效果 使用 XML中: <com.airsaid.diffuseview.widget.DiffuseView android:id=&q ...

  5. 【MFC】基于opencv的趣味相机

    为了参加学校的科技节,故用mfc随手制作了一个名为<趣味相机>的小程序: 其中对图形图像处理运用到了opencv. 效果图 这界面逼格低了点╭(╯^╰)╮ 有兴趣的朋友可以在此下载尝试:h ...

  6. hdu3926 Hand in Hand 判断同构

    因为每个人小朋友只有两只手,所以每个点最多只有2度.图有可能是环.链,以及环和链构成的复杂图. 如何判断两幅图是否相似呢?判断相似是判断两幅图的圈的数量,以及构成圈的点数是否相同.还有判断链的数目和构 ...

  7. axis2服务器搭建

    一. axis2服务器搭建 简单起见, axis2r搭建采用较为简单的一种方式, 即将服务类和services.xml打成.aar包发布. 1. 下载部署axis2 http://axis.apach ...

  8. Angular 通过constant(name,value),value(name,value)创建服务

    区别: constant()可以将已经存在的变量值注册为服务,并将其注入到应用的其他部分中,他的value可以是值,也可以是对象.通过他来配置数据,也就是说可以在config里注入,但是他是不可以修改 ...

  9. 基于libVLC的视频播放器

    本文来自于:http://blog.csdn.net/leixiaohua1020/article/details/42363079 最简单的基于libVLC的例子:最简单的基于libVLC的视频播放 ...

  10. RxSwiftライブラリの作り方 〜Observer/Observable編〜

    RxSwiftライブラリの作り方をご紹介します.一つの記事ですべてを説明するのは非常に厳しいので.まず Observer や Observable といった基本的なコンポーネントとその周辺について.ひ ...