BZOJ 3155: Preprefix sum( 线段树 )
阅读原文时间:2021年04月22日阅读:1

刷刷水题…

前缀和的前缀和…显然树状数组可以写…然而我不会, 只能写线段树了

把改变成加, 然后线段树维护前缀和, 某点p加, 会影响前缀和pre(x)(p≤x≤n), 对[p, n]这段区间加即可, 然后query就求[1, p]的和即可

---------------------------------------------------------------------------------

#include

using namespace std;

typedef long long ll;

const int maxn = 100009;

int L, R, v, seq[maxn], N;

ll cnt[maxn];

struct Node {

Node *l, *r;

ll add, sum;

Node() {

add = 0;

}

inline void pushdown() {

if(add) {

l->add += add;

r->add += add;

add = 0;

}

}

inline void update(int len) {

if(l) sum = l->sum + r->sum;

sum += add * len;

if(!l) add = 0;

}

} pool[maxn << 1], *pt = pool, *root;

void build(Node* t, int l, int r) {

if(l == r) {

t->sum = cnt[l];

} else {

int m = (l + r) >> 1;

build(t->l = pt++, l, m);

build(t->r = pt++, m + 1, r);

t->update(r - l + 1);

}

}

void modify(Node* t, int l, int r) {

if(L <= l && r <= R) {

t->add += v;

} else {

t->pushdown();

int m = (l + r) >> 1;

L <= m ? modify(t->l, l, m) : t->l->update(m - l + 1);

m < R ? modify(t->r, m + 1, r) : t->r->update(r - m);

}

t->update(r - l + 1);

}

ll query(Node* t, int l, int r) {

if(L <= l && r <= R) return t->sum;

int m = (l + r) >> 1;

t->pushdown();

t->l->update(m - l + 1); t->r->update(r - m);

return (L <= m ? query(t->l, l, m) : 0) + (m < R ? query(t->r, m + 1, r) : 0);

}

int main() {

int m; scanf("%d%d", &N, &m);

for(int i = 1; i <= N; i++) scanf("%d", seq + i);

cnt[0] = 0;

for(int i = 1; i <= N; i++) cnt[i] += cnt[i - 1] + seq[i];

build(root = pt++, 1, N);

while(m--) {

char s[10]; scanf("%s", s);

if(s[0] == 'M') {

int p, v; scanf("%d%d", &p, &v);

::v = v - seq[p];

seq[p] = v;

L = p; R = N;

modify(root, 1, N);

} else {

L = 1;

  scanf("%d", &R);

printf("%lld\n", query(root, 1, N));

}

}

return 0;

}

---------------------------------------------------------------------------------

Time Limit: 1 Sec  Memory Limit: 512 MB
Submit: 765  Solved: 341
[Submit][Status][Discuss]

第一行给出两个整数N,M。分别表示序列长度和操作个数

接下来一行有N个数,即给定的序列a1,a2,….an

接下来M行,每行对应一个操作,格式见题目描述

对于每个询问操作,输出一行,表示所询问的SSi的值。

5 3
1 2 3 4 5
Query 5
Modify 3 2
Query 5

35
32

1<=N,M<=100000,且在任意时刻0<=Ai<=100000

Katharon+#1

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章