题目描述

给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值。

输入格式

第一行输入一个数字\(n\)。

第二行输入\(n\)个数字,第\(i\)个数字为\(a_{i}\),以空格隔开。

接下来输入\(n\)行询问,每行输入四个数字\(opt\)、\(l\)、\(r\)、\(c\),以空格隔开。

若\(opt = 0\),表示将位于\([l, r]\)的之间的数字都加\(c\)。

若\(opt = 1\),表示询问\(a_{r}\)的值(\(l\)和\(c\)忽略)。

输出格式

对于每次询问,输出一行一个数字表示答案。

样例

样例输入

4

1 2 2 3

0 1 3 1

1 0 1 0

0 1 2 2

1 0 2 0

样例输出

2

5

数据范围与提示

对于所有的数据,\(1 \leq n \le 50000\) ,\(-2^{31} \leq others、ans \le 2_{31} - 1\) 。

题解

这是一道很好的分块入门题。

所谓分块,就是一种通过将一个序列分成多块后,在每块上打标记以实现快速区间修改,区间查询的一种算法。其均摊时间复杂度为\(\Theta\sqrt{n}\)。

在一般情况下,每个块的长度都为\(\sqrt{n}\)。

分块,被尊称为优雅的暴力,因此它的代码难度也不算高。总之,比线段树、树状数组等毒瘤数据结构的代码难度低。

我们需要建立三个数组:

  • \(a[]\),为题目中输入的序列;
  • \(b[]\),记录每个序列中的每个数在那一块;
  • \(add[]\),为序列的标记数组。

话不多说,上代码。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>//头文件准备 using namespace std;//使用标准名字空间 inline int gi()//快速读入
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-')f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
} int a[50005], b[50005], add[50005], len, n, m;//a[],b[],add[]的意思如分析,len为每一块的长度,n为序列长度,m为询问个数,在本题中=n。 inline void modify(int l, int r, int x)//区间修改的自定义函数
{
for (int i = l; i <= min(r, b[l] * len); i++) a[i] = a[i] + x;//增加序列中的数
if (b[l] != b[r])//如果要修改的不在同一个块中
{
for (int i = (b[r] - 1) * len + 1; i <= r; i++) a[i] = a[i] + x;//继续增加序列中的数
}
for (int i = b[l] + 1; i <= b[r] - 1; i++) add[i] = add[i] + x;//给区间内的数增加标记
} int main()//进入主函数
{
n = gi();//输入元素个数
len = sqrt(n);//求出每个块的长度
for (int i = 1; i <= n; i++) a[i] = gi();//输入序列中的数
for (int i = 1; i <= n; i++) b[i] = (i - 1) / len + 1;//求出序列中的数分别属于哪一个块
for (int p = 1; p <= n; p++)
{
int fl = gi(), l = gi(), r = gi(), w = gi();//输入操作的描述
if (!fl)//如果是修改
{
modify(l, r, w);//修改区间内的数
}
else//否则就是求出某个数
{
printf("%d\n", a[r] + add[b[r]]);//输出这个位置的数的标记和它在序列中原本的数的和
}
}
return 0;//完美结束
}

题解【loj6277】数列分块入门1的更多相关文章

  1. 题解——loj6277 数列分块入门1(分块)

    分块裸题 然后就是记得左右边界处理和分块的初始化 忘了初始化会被卡成暴力 #include <cstdio> #include <algorithm> #include < ...

  2. 题解——loj6281 数列分块入门5 (分块)

    分块 若块内最大值为0或1,则不用再开方 然后暴力修改 可以证明,如果开方后向下取整,则最多开方4次一个数就会变成0或1 #include <cstdio> #include <cm ...

  3. 题解——loj6280 数列分块入门4 (分块)

    分块维护一个区间和 然后记得更新的时候左边角块的tag不要打错到右边角块 #include <cstdio> #include <algorithm> #include < ...

  4. [LOJ6277]数列分块入门 1

    题目大意: 给你一个长度为$n(n\leq 50000)$的序列$A$,支持进行以下两种操作: 1.将区间$[l,r]$中所有数加上$c$: 2.询问$A_r$的值.思路: 分块. 对于整块的数据打标 ...

  5. loj6277 数列分块入门题1

    裸题分块. #include <bits/stdc++.h> using namespace std; ],b[],n,m,t1,t2,t3,t4,sq; int main(){ ios: ...

  6. 题解——loj6279 数列分块入门3 (分块)

    用set维护有序序列 或许sort也可以,但这题的前驱定义是严格小于 所以要去重 然后就是记得自己打的加法tag在query的时候一定要算上 话说这题数据有点fake啊忘了查询算上自己的标记了还有70 ...

  7. 题解——loj6278 数列分块入门2 (分块)

    查询小于k的值 注意lower_bound一定要减去查找的起始位置得到正确的位置 调了快两天 淦 #include <cstdio> #include <algorithm> ...

  8. LOJ6277~6285 数列分块入门

    Portals 分块需注意的问题 数组大小应为,因为最后一个块可能会超出的范围. 当操作的区间在一个块内时,要特判成暴力修改. 要清楚什么时候应该+tag[t] 数列分块入门 1 给出一个长为的数列, ...

  9. 数列分块入门九题(一):LOJ6277~6279

    Preface 分块,一个神奇的暴力算法.可以把很多\(O(n^2)\)的数据结构题的暴力优化到常数极小的\(O(n\sqrt n)\).当一些毒瘤题无法用线段树,主席树,平衡树,树状数组...... ...

  10. LibreOJ6279. 数列分块入门 3 题解

    题目链接:https://loj.ac/problem/6279 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的前驱(比其 ...

随机推荐

  1. luoguP5219 无聊的水题 I 多项式快速幂

    有一个幼儿园容斥:最大次数恰好为 $m=$  最大次数最多为 $m$ - 最大次数最多为 $m-1$. 然后来一个多项式快速幂就好了. code: #include <cmath> #in ...

  2. CF895C Square Subsets [线性基]

    线性基的题- 考虑平方数只和拆解质因子的个数的奇偶性有关系 比如说你 \(4\) 和 \(16\) 的贡献都是一样的.因为 \(4 = 2^2 , 16 = 2^4\) \(2\) 和 \(4\) 奇 ...

  3. Java集合之Arrays 剖析

    Arrays工具类位于 java.util 包下,是一个比较常用的工具类,其可以针对数组进行各种操作,比如赋值.排序.搜索等等.在项目过程中我们针对数组的有关操作,如果不方便直接操作,均可通过调用此类 ...

  4. JavaScript 删除某个数组中指定的对象和删除对象属性

    Javascript: 删除指定对象:使用过程中只适合删除对象,如果数组中添加的是类型Function的话是删除不了的. function removeObjWithArr(_arr,_obj) { ...

  5. 前端开发 css、less编写规范

    壹 ❀ 引 早在大半年前,我在负责整理定义了前端组JavaScript开发规范与less.css样式开发规范.一直想将两个规范整理成文章,但在整理了JavaScript规范后,我花了较多的时间在学习J ...

  6. 2019.2.21 T2题解

    meet 大概思路就是 , 找出相交的路径 , 判断方向 , 分类讨论.. 假设已经找出了相交路径 ... 若方向相同 , 则找到相交路径上边权的最大值 , 若最大值>出发时间差 , 则可行. ...

  7. Python之六:模块

    模块包含了大量的函数方法和变量,我们可以用下面的语句调用模块: import 模块名 这样我们就可以在后面的语句中使用模块中的函数或者变量了.调用时只需用    模块名.函数名的方式调用即可 from ...

  8. phpstudy+phpstorm 浏览器没有解析php文件,直接显示源码

    用phpstorm编辑完项目,右键浏览器预览时页面报错:502 Bad Gateway PhpStorm 2019.1 此时默认打开的地址是:localhost:63339/开头的一长串…… 查资料说 ...

  9. 将字符串转换为double类型的list

    var data=“3.039,3.977,3.677,5.855,12.341,6.771”; 方法一: var result=datas.Split(',').ToList().ConvertAl ...

  10. 占位 RK

    占位 RK include: RK403 RK404