「説明」は、列の数は、エントリ1ブロックLibreOJ6277

ポータル

Portal1:LibreOJ

説明

所与の長さ\(\ N-)は列の数であり、\(\ N-)操作、添加間隔、1つのチェックポイント値を伴う操作。

入力

デジタルの第一の入力ライン(\ \ N-)

第2の行入力\(\ N-)桁、\(Iは\)の桁\(a_iを\) スペースで区切ら。

今入力\(N- \)問い合わせの行を、行ごとに4桁\(OPTの\)、\ (Lの\)、\ (R&LT \)、\ (C \)スペースで区切ら。

場合\(\ textttオプト= {0} \) 位置を表し\([L、R] \ ) 番号が間に追加される\(C \)

もし\(\ texttt OPT = {}。1 \)問い合わせを示す、(a_iを\)\値(\(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

ヒント

ため\(100 \%の\)データ、\(1 \ N-LE \ 50000ル、31 -2 ^ {} \ルその他、ANS \ル31は{2} ^ -である。1 \)

溶液

ブロックへの最初のシーケンス(\ \のSQRT {N} \ ) ブロック、加算間隔、左右のトリムピース激しいプロセス、ブロック全体遅延更新フラグ。シングルポイントの評価、限り怠惰なラベルされたことのブロックはそれを追加した、独自の価値。

コード

#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;
}

アタッチメント

テストデータダウンロード:https://www.lanzous.com/i51c8of

おすすめ

転載: www.cnblogs.com/shenxiaohuang/p/11221164.html