首页 > 编程语言 > 详细

[LOJ132] 树状数组 3 :区间修改,区间查询

时间:2020-04-14 22:12:30      阅读:88      评论:0      收藏:0      [点我收藏+]

维护序列,支持区间加、区间求和。\(n \leq 10^6\)

Solution

由于数据较大,不得不使用二次差分 BIT

设原数列为 \(a_i\),令 \(a_i = \sum_{j=1}^i d_i\),则

\[\sum_{i=1}^k a_i = (k+1) \sum_{i=1}^k d_i-\sum_{i=1}^k id_i \]

于是我们先对原始 \(a_i\) 求出 \(d_i\),然后用两个 BIT 来维护即可

修改时只需要将 \(d_l+x\),将 \(d_{r+1}-x\)idx 也对应修改)

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 2000005;
#define lowbit(x) ((x)&(-(x)))

void add(int *ar, int i, int v) {
	for (; i < N; ar[i] += v, i += lowbit(i));
}
int sum(int *ar, int i) {
	int s = 0;
	for (; i > 0; s += ar[i], i -= lowbit(i));
	return s;
}

int a[N],d[N],id[N],t1,t2,t3,t4,n,m;

int getans(int k) {
    return (k)*sum(d,k)-sum(id,k);
}

signed main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i], add(d,i,a[i]-a[i-1]), add(id,i,(i-1)*(a[i]-a[i-1]));
    for(int i=1;i<=m;i++) {
        cin>>t1>>t2>>t3;
        if(t1==1) {
            cin>>t4;
            add(d,t2,t4);
            add(d,t3+1,-t4);
            add(id,t2,(t2-1)*t4);
            add(id,t3+1,-(t3)*t4);
        }
        else {
            cout<<getans(t3)-getans(t2-1)<<endl;
        }
    }
}

[LOJ132] 树状数组 3 :区间修改,区间查询

原文:https://www.cnblogs.com/mollnn/p/12700977.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!