XiaoHuang's Space
XiaoHuang's Space
XiaoHuang
May the force be with you.
『题解』LibreOJ6277 数列分块入门 1
Posted: Dec 11, 2019
Last Modified: Dec 13, 2019
This article was last modified days ago. The content of this post may be outdated!

Portal

Portal1: LibreOJ

Description

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

Input

第一行输入一个数字$n$。

第二行输入$n$个数字,第$i$个数字为$a_i$,以空格隔开。

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

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

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

Output

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

Sample Input

4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0

Output

2
5

Hint

对于$100\%$的数据,$1 \le n \le 50000, -2^{31} \le others, ans \le 2^{31} - 1$。

Solution

分块,先将序列分成$\sqrt{n}$块,区间加法时,整块左右的边角料暴力处理,整的块来更新懒标记。单点求值时,只要把自己的值与它所在的块的懒标记加起来就可以了。

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

const int MAXN = 50005;
int n, a[MAXN], bl[MAXN], tag[MAXN];
int main() {
    scanf("%d", &n);
    int block = (int)sqrt(n);//总块数
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        bl[i] = (i - 1) / block;//分块
    }
    for (int i = 1; i <= n; i++) {
        int opt, x, y, val;
        scanf("%d%d%d%d", &opt, &x, &y, &val);
        if (opt == 0) {
            if (bl[x] == bl[y]) {
                for (int i = x; i <= y; i++)
                    a[i] += val;//如果区间不包含任何块
            } else {
                for (; bl[x] == bl[x - 1]; x++)
                    a[x] += val;//处理边角料
                for (; bl[y] == bl[y + 1]; y--)
                    a[y] += val;//处理边角料
                for (int i = x; i <= y; i += block)
                    tag[bl[i]] += val;//更新整块的懒标记
            }
        } else printf("%d\n", a[y] + tag[bl[y]]);//单点求值
    }
    return 0;
}

Attachment

测试数据下载:https://www.lanzous.com/i51c8of

Article License: CC BY-NC-ND 4.0
Article Author: XiaoHuang
  1. 1. Portal
  2. 2. Description
  3. 3. Input
  4. 4. Output
  5. 5. Sample Input
  6. 6. Output
  7. 7. Hint
  8. 8. Solution
  9. 9. Code
  10. 10. Attachment
Newer Post
『题解』LibreOJ6278 数列分块入门 2
Older Post
『工具』对拍器
Buy me a beer?
-->
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×