链接:

https://loj.ac/problem/6279

题意:

给出一个长为 的数列,以及 个操作,操作涉及区间加法,询问区间内小于某个值 的前驱(比其小的最大元素)。

思路:

同样的分块加二分,只不过是更新值

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. //#include <memory.h>
  6. #include <queue>
  7. #include <set>
  8. #include <map>
  9. #include <algorithm>
  10. #include <math.h>
  11. #include <stack>
  12. #include <string>
  13. #include <assert.h>
  14. #include <iomanip>
  15. #define MINF 0x3f3f3f3f
  16. using namespace std;
  17. typedef long long LL;
  18. const int MAXN = 1e5+10;
  19. int a[MAXN];
  20. int Rank[MAXN], Tag[MAXN];
  21. vector<int> Vec[MAXN];
  22. int part, n;
  23. void Re(int pos)
  24. {
  25. Vec[pos].clear();
  26. for (int i = (pos-1)*part+1;i <= pos*part;i++)
  27. Vec[pos].push_back(a[i]);
  28. sort(Vec[pos].begin(), Vec[pos].end());
  29. }
  30. void Update(int l, int r, int c)
  31. {
  32. for (int i = l;i <= min(Rank[l]*part, r);i++)
  33. a[i] += c;
  34. Re(Rank[l]);
  35. if (Rank[l] != Rank[r])
  36. {
  37. for (int i = max(l, (Rank[r]-1)*part+1);i <= r;i++)
  38. a[i] += c;
  39. Re(Rank[r]);
  40. }
  41. for (int i = Rank[l]+1;i <= Rank[r]-1;i++)
  42. {
  43. Tag[i] += c;
  44. }
  45. }
  46. int Query(int l, int r, int c)
  47. {
  48. int res = -1;
  49. for (int i = l;i <= min(Rank[l]*part, r);i++)
  50. {
  51. if (a[i]+Tag[Rank[l]] < c)
  52. res = max(res, a[i]+Tag[Rank[l]]);
  53. }
  54. if (Rank[l] != Rank[r])
  55. {
  56. for (int i = max((Rank[r]-1)*part+1, l);i <= r;i++)
  57. {
  58. if (a[i]+Tag[Rank[r]] < c)
  59. res = max(res, a[i]+Tag[Rank[r]]);
  60. }
  61. }
  62. for (int i = Rank[l]+1;i <= Rank[r]-1;i++)
  63. {
  64. int pos = lower_bound(Vec[i].begin(), Vec[i].end(), c-Tag[i])-Vec[i].begin();
  65. if (pos >= 1)
  66. res = max(res, Vec[i][pos-1]+Tag[i]);
  67. }
  68. return res;
  69. }
  70. int main()
  71. {
  72. scanf("%d", &n);
  73. part = sqrt(n);
  74. for (int i = 1;i <= n;i++)
  75. scanf("%d", &a[i]);
  76. for (int i = 1;i <= n;i++)
  77. {
  78. Rank[i] = (i-1)/part+1;
  79. Vec[Rank[i]].push_back(a[i]);
  80. }
  81. for (int i = 1;i <= Rank[n];i++)
  82. sort(Vec[i].begin(), Vec[i].end());
  83. int op, l, r, c;
  84. for (int i = 1;i <= n;i++)
  85. {
  86. scanf("%d %d %d %d", &op, &l, &r, &c);
  87. if (op == 0)
  88. Update(l, r, c);
  89. else
  90. printf("%d\n", Query(l, r, c));
  91. }
  92. return 0;
  93. }

LOJ-6279-数列分块入门3(分块, 二分)的更多相关文章

  1. LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))

    #6279. 数列分块入门 3 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 3   题目描述 给 ...

  2. LOJ 6279 数列分块入门3

    嗯... 题目链接:https://loj.ac/problem/6279 这道题在分块的基础上用vc数组记录,然后最后分三块,两边暴力枚举找前驱,中间lower_bound找前驱. AC代码: #i ...

  3. LOJ#6279. 数列分块入门 3

    区间加值还是正常的操作,查找前驱的时候用lower_bound查找,然后范围所在位置的值 #include<map> #include<set> #include<cti ...

  4. LOJ.6284.数列分块入门8(分块)

    题目链接 \(Description\) 给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c. \(Solution\) 模拟一些数据可以发现,询问后 ...

  5. LibreOJ 6279 数列分块入门 3(分块+排序)

    题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...

  6. LOJ.6281.数列分块入门5(分块 区间开方)

    题目链接 int内的数(也不非得是int)最多开方4.5次就变成1了,所以还不是1就暴力,是1就直接跳过. #include <cmath> #include <cstdio> ...

  7. LibreOJ 6277 数列分块入门 1(分块)

    题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...

  8. LibreOJ 6278 数列分块入门 2(分块)

     题解:非常高妙的分块,每个块对应一个桶,桶内元素全部sort过,加值时,对于零散块O(sqrt(n))暴力修改,然后暴力重构桶.对于大块直接整块加.查询时对于非完整块O(sqrt(n))暴力遍历.对 ...

  9. [Libre 6281] 数列分块入门 5 (分块)

    水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteu ...

随机推荐

  1. Altera DDR2 IP核学习总结1-----------SRAM,DRAM

    SRAM,DRAM,SDRAM和DDR2这些芯片详解网上铺天盖地的各种资料都有,这里只是根据个人习惯做一下总结,方便记忆. 详细资料可以参考https://wenku.baidu.com/view/3 ...

  2. 【LeetCode】309、最佳买卖股票时机含冷冻期

    Best Time to Buy and Sell Stock with Cooldown 题目等级:Medium 题目描述: Say you have an array for which the ...

  3. Linux解决Python调用Matlab函数无法导入matlab.engine问题及其他注意事项

    问题描述 Linux系统,根据matlab官方文档说明,利用Matlab中的API来实现Python调用Matlab函数.具体方法见文档: https://ww2.mathworks.cn/help/ ...

  4. Python中调用c语言(简单版)

    Python中有时需要调用c程序中的函数.使用ctype库可以很方便地调用c语言.现说明方法,以及注意事项. c程序编译为.so文件: 我们需要的c语言文件为test.c,要从其中调用func(x,y ...

  5. python 基础复习

    1.简述cpu.内存.硬盘的作用 cpu (1)cpu:处理逻辑运算.算术运算 (2)cpu:接受指令传给电脑硬件,让其运行 内存: (1)内存:从硬盘中读取数据,供其cpu调取指令运行,短暂的存贮数 ...

  6. java script 的注释与分号

    // 单行注释 /**/多行注释 在js 中 变量.函数和操作符都是区分大小写的 什么是标识符 变量.函数.属性的名字.或者函数的参数. 变量的命名规范:不能以数字开头. 变量声明: var  nam ...

  7. XSS-笔记

     Cross Site Script  跨站脚本 是一种客户端代码的注入  而命令注入.sql注入都是客户端代码的注入.   XSS攻击行为的目标为:1.窃取目标的cookie信息 2.执行CSRF脚 ...

  8. [转帖]Ubuntu 对应内核版本

    带有相应Linux内核版本的Ubuntu版本列表 https://www.helplib.com/ubuntu/article_155943   问题: 是否有带有默认对应的Linux内核版本的Ubu ...

  9. 【转帖】技术选型之Docker容器引擎

    技术选型之Docker容器引擎 https://segmentfault.com/a/1190000019462392 图过不来的 原作者写的挺好的 题外话 最近对Docker和Kubernetes进 ...

  10. Oracle常用启停命令

    一.监听启停 Oracle监听的启动.停止和状态查看 Oracle监听启动: lsnrctl start Oracle监听停止: lsnrctl stop Oracle监听状态 lsnrctl sta ...