Ryuji doesn't want to study (树状数组)

Ryuji doesn’t want to study (树状数组)

Ryuji is not a good student, and he doesn’t want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]a[i].

Unfortunately, the longer he learns, the fewer he gets.

That means, if he reads books from lll to rrr, he will get a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r]a[l] \times L + a[l+1] \times (L-1) + \cdots + a[r-1] \times 2 + a[r]a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r] (LLL is the length of [ lll, rrr ] that equals to r−l+1r - l + 1r−l+1).

Now Ryuji has qqq questions, you should answer him:

  1. If the question type is 111, you should answer how much knowledge he will get after he reads books [ lll, rrr ].

  2. If the question type is 222, Ryuji will change the ith book’s knowledge to a new value.
    Input

First line contains two integers nnn and qqq (nnn, q≤100000q \le 100000q≤100000).

The next line contains n integers represent aia[i]( a[i] \le 1e9)ai .

Then in next qqq line each line contains three integers aaa, bbb, ccc, if a=1a = 1a=1, it means question type is 111, and bbb, ccc represents [ lll , rrr ]. if a=2a = 2a=2 , it means question type is 222 , and bbb, ccc means Ryuji changes the bth book’ knowledge to ccc
Output

For each question, output one line with one integer represent the answer.
样例输入

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

样例输出

10
8

题目来源

ACM-ICPC 2018 徐州赛区网络预赛

题意:

给定一个数组 a [ N ] ,有两种操作,

操作1,给定 l , r , a [ l ] × L + a [ l + 1 ] × ( L 1 ) + + a [ r 1 ] × 2 + a [ r ] 的值

(L is the length of [ l, r ] that equals to r - l + 1).

操作2, 给定 x , y 使 a [ x ] = y

N M 种操作,对于每个操作1输出计算结果。

分析:

我们将要求的式子变形

i = l r a i ( r i + 1 ) = i = l r a i × [ ( r + 1 ) i ] = ( r + 1 ) i = l r a i i = l n a i × i

这样我们可以构造并维护两个数组的树状数组,一个是a[i]的树状数组C1[i],一个是 a[i]*i的树状数组C2[i]。

注意这里是修改值而不是增加值,所以增加的是“新值与旧值得差”,并且要注意把原数组a[i]的值重新赋值。

code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
ll a[maxn];
int n,m;
ll c1[maxn],c2[maxn];
void init(){
    memset(a,0,sizeof(a));
    memset(c1,0,sizeof(c1));
    memset(c2,0,sizeof(c2));
}
int lowbit(int x){
    return x & (-x);
}
void add1(int x,ll val){
    while(x <= n){
        c1[x] += val;
        x += lowbit(x);
    }
}
ll query1(int x){
    ll ans = 0;
    while(x > 0){
        ans += c1[x];
        x -= lowbit(x);
    }
    return ans;
}
void add2(int x,ll val){
    while(x <= n){
        c2[x] += val;
        x += lowbit(x);
    }
}
ll query2(int x){
    ll ans = 0;
    while(x > 0){
        ans += c2[x];
        x -= lowbit(x);
    }
    return ans;
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        init();
        for(int i = 1; i <= n; i++){
            scanf("%lld",&a[i]);
            add1(i,a[i]);
            add2(i,i*a[i]);
        }
        ll op,l,r;
        for(int i = 1; i <= m; i++){
            scanf("%lld%lld%lld",&op,&l,&r);
            if(op == 1)
                printf("%lld\n",(r + 1) * (query1(r) - query1(l-1)) - (query2(r) - query2(l-1)));
            else{
                add1(l,r - a[l]);
                add2(l,l * r - l * a[l]);
                a[l] = r;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codeswarrior/article/details/82621597