先说一个小trick,一开始我们把他赋值成是红、白相间的,查询就查询的是全红或全白即可。

然后就可以做啦

题解里面好像都是线段树

暴力的题解好像都被del了

貌似暴力交上去也过不了了

然后我想说

分块大法好!

把同学们他分成\(\lfloor\sqrt N\rfloor\)块

每块维护八个信息:

左边连续白长度,右边连续白长度,块内连续白长度,是否全白,

左边连续红长度,右边连续红长度,块内连续红长度,是否全红,

记录两个不变的信息:

id(废话),块的长度

每次更新,找到那个同学在哪个块,整块全部暴力更新,根号N

怎么更新,整个快全扫一遍,统计白的数量和红的数量能把是否全白全红做了,中途统计当前连续白红数量能把最长块内连续长度做了

然后从块左端往右扫,右端往左扫,把左右两端的长度高了

每次查询,也是\(\sqrt N\),乱搞搞

怎么搞,先枚举两种颜色,然后枚举所有区块,更新一个当前能延伸的长度,如果这个区块全是一种颜色就+=(可以连上),否则就直接等于他右端的长度,具体看代码

复杂度大概\(O(M\sqrt N)\)

由于我经常用调试输出,所以我就没有删除调试输出

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cmath>
  4. using namespace std;
  5. int n, m, size;
  6. int a[20010], id[20010];
  7. int len[200], l[200], r[200];
  8. struct info
  9. {
  10. bool all;
  11. int l, r, x;
  12. }b[200][2];
  13. int query();
  14. void print()
  15. {
  16. printf("输出调试信息\n");
  17. for (int i = 1; i <= n; i++)
  18. printf("%d%c", a[i], i == n ? '\n' : ' ');
  19. for (int i = 1; i <= id[n]; i++)
  20. {
  21. printf("第%d块 (%d, %d)", i, l[i], r[i]);
  22. for(int t = 0; t <= 1; t++)
  23. printf("[%d %d %d %d]%c", b[i][t].all, b[i][t].l, b[i][t].x, b[i][t].r, t?'\n':' ');
  24. }
  25. printf("当前答案%d\n", query());
  26. }
  27. //更新区块x
  28. void update(int x)
  29. {
  30. // printf("更新了区块%d\n", x);
  31. int t[2] = {0, 0}, f[2] = {0, 0};
  32. b[x][0].x = b[x][1].x = 0;
  33. for (int i = l[x]; i <= r[x]; i++)
  34. {
  35. t[a[i]]++;
  36. f[a[i]]++;
  37. if(a[i] != a[i - 1])
  38. {
  39. b[x][a[i - 1]].x = max(b[x][a[i - 1]].x, f[a[i - 1]]);
  40. f[a[i - 1]] = 0;
  41. }
  42. }
  43. b[x][a[r[x]]].x = max(b[x][a[n]].x, f[a[r[x]]]);
  44. b[x][0].all = (t[0] == len[x]);
  45. b[x][1].all = (t[1] == len[x]);
  46. b[x][a[l[x]]].l = 1;
  47. b[x][a[l[x]] ^ 1].l = 0;
  48. b[x][a[r[x]]].r = 1;
  49. b[x][a[r[x]] ^ 1].r = 0;
  50. for (int i = l[x] + 1; a[i] == a[i - 1] && i <= r[x]; i++)
  51. b[x][a[l[x]]].l++;
  52. for (int i = r[x] - 1; a[i] == a[i + 1] && i >= l[x]; i--)
  53. b[x][a[r[x]]].r++;
  54. }
  55. //查询当前状态的最大值
  56. int query()
  57. {
  58. int maxlength[2] = {0, 0}, nowlength[2] = {0, 0};
  59. for (int t = 0; t <= 1; t++)
  60. {
  61. for (int i = 1; i <= id[n]; i++)//枚举所有区块
  62. {
  63. maxlength[t] = max(maxlength[t], b[i][t].l + nowlength[t]);
  64. maxlength[t] = max(maxlength[t], b[i][t].x);
  65. if(b[i][t].all == 1)
  66. nowlength[t] += len[i];
  67. else
  68. nowlength[t] = b[i][t].r;
  69. }
  70. maxlength[t] = max(maxlength[t], nowlength[t]);
  71. }
  72. return max(maxlength[0], maxlength[1]);
  73. }
  74. int main()
  75. {
  76. scanf("%d%d", &n, &m);
  77. for (int i = 1; i <= n; i++)
  78. a[i] = (i & 1);
  79. size = sqrt(n);
  80. for (int i = 1; i <= n; i++)
  81. {
  82. id[i] = (i - 1) / size + 1;
  83. len[id[i]]++;
  84. if ((i - 1) % size == 0)
  85. l[id[i]] = i;
  86. if (i % size == 0)
  87. r[id[i]] = i;
  88. }
  89. r[id[n]] = n;
  90. for (int i = 1; i <= id[n]; i++)
  91. update(i);
  92. // print();
  93. for (int x, i = 1; i <= m; i++)
  94. {
  95. scanf("%d", &x);
  96. a[x] ^= 1;
  97. update(id[x]);
  98. // print();
  99. printf("%d\n", query());
  100. }
  101. return 0;
  102. }

瞎扯几句

据说写分快是对出题人的不尊重??但是这题难度标签对我不尊重2333。。。

一个线段树模板就是绿题了,这题黄题 显然不用线段树能过,所以我就写了分块

经验/启示:以后懒得写线段树但是又比较勤快可以试试分块

luogu2253 好一个一中腰鼓!的更多相关文章

  1. 洛谷 P2253 好一个一中腰鼓! 题解

    P2253 好一个一中腰鼓! 题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:"忽一人 ...

  2. 洛谷P2253 好一个一中腰鼓!

    题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢 ...

  3. 洛谷 P2253 好一个一中腰鼓!

    题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢 ...

  4. P2253 好一个一中腰鼓!

    题意:给你一个序列,初始是0,每次一个操作,把一个数^=1 每次求出最长01串的长度 正解:线段树(虽然暴力能过) 对于每个区间,记录三个值 lmax,以l为首的01串长度 rmax,以r为尾的01串 ...

  5. 「Luogu P2253 好一个一中腰鼓!」

    就这道题的理论难度来说绿题是有点低了,但是这道题的实际难度来看,顶多黄题,所以建议加强数据或出数据升级版. 前置芝士 线段树:具体可以看我的另一篇文章. 具体做法 暴力的方法想必都会,所以来讲一下正解 ...

  6. 把一个一中的字段更新另一个表中的t-sql

    UPDATE dbo.CommDescr SET Descr=(SELECT ba.content FROM dbo.blog_article ba WHERE ba.id=3) WHERE Comm ...

  7. noip2017考前整理(未完)

    快考试了,把我以前写过的题回顾一下.Noip2007 树网的核:floyd,推出性质,暴力.Noip2008 笨小猴:模拟Noip2008 火柴棒等式:枚举Noip2008 传纸条:棋盘dpNoip2 ...

  8. mybatis 常用

    1.新增时获得主键 <insert ...> <selectKey resultType="java.lang.Integer" keyProperty=&quo ...

  9. [HNOI2018]爆零记

    Day 0 完全不知道做什么. 打了一个splay板子,还没调出来emmmmm 不想做题目,最后做的一题是[HNOI2016]的超(sha)难(bi)题网络. 当我希望省选能出一下树剖时,旁边的大佬跟 ...

随机推荐

  1. 用Unreal Engine绘制实时CG影像

    转自:http://www.unrealchina.net/portal.php?mod=view&aid=225 近年来,对实时CG的关心热度越来越高,但要想弥补与预渲染方式的差异并不是那么 ...

  2. js防止重复点击

    表单元素 disabled 没有之一. el.prop('disabled', true); ajax({}).done(function() { el.prop('disabled', false) ...

  3. 程序中使用log4J打印信息的两种方式

    (1)通过org.apache.commons.logging.Log 接口实例化: public static Log log = LogFactory.getLog(String name); p ...

  4. Python 标准库 -> Pprint 模块 -> 用于打印 Python 数据结构

    使用 pprint 模块 pprint 模块( pretty printer ) 用于打印 Python 数据结构. 当你在命令行下打印特定数据结构时你会发现它很有用(输出格式比较整齐, 便于阅读). ...

  5. executeUpdate,executeQuery,executeBatch 的区别

    executeQuery : 用于实现单个结果集,例如: Select 一般使用executeQuery 就是来实现单个结果集的工具 executeUpdate 用于执行 INSERT.UPDATE ...

  6. ssh框架搭建实例代码教程步骤

    http://blog.csdn.net/u010539352/article/details/49255729

  7. JavaScript 的异步和单线程

    问题 Q:下面的代码是否能满足sleep效果? var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert( ...

  8. GBK、GB2312和UTF-8编码区分

    GBK包含全部中文字符, GBK的文字编码是双字节来表示的,即不论中.英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1. 至于UTF-8编码则是用以解决国际上字符的一种多字节编码,它对 ...

  9. ThinkPHP的URL模式

    ThinkPHP的URL模式有四种,默认是PATHINFO模式,其他三种分别为:普通模式.REWRITE和兼容模式. 一.PATHINFO模式 浏览器输入格式为: http://localhost/d ...

  10. php学习笔记-foreach循环

    顾名思义,foreach是for each的连写,不是for reach.意思就是对数组中的每个元素都要处理一次. foreach只能用来处理数组. 有两种用法,先看第一种. foreach(arra ...