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].

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

That means, if he reads books from ll to rr, he will get 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] (LL is the length of [ ll, rr ] that equals to r - l + 1r−l+1).

Now Ryuji has qq questions, you should answer him:

11. If the question type is 11, you should answer how much knowledge he will get after he reads books [ ll, rr ].

22. If the question type is 22, Ryuji will change the ith book's knowledge to a new value.

Input

First line contains two integers nn and qq (nn, q \le 100000q≤100000).

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

Then in next qq line each line contains three integers aa, bb, cc, if a = 1a=1, it means question type is 11, and bb, ccrepresents [ ll , rr ]. if a = 2a=2 , it means question type is 22 , and bb, cc means Ryuji changes the bth book' knowledge to cc

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

//题目大意:大小为n的数组,q个询问,输入a,b,c,若a=1,表示根据题目公式求出求b~c的和,若a=2,将a[b]的值更换为c;

//思路:线段树; 我们发现,在【L,R】的a数组求和时,a[index]的前缀qz1=(R-L+1)-(index-L);假如【L,R】由【L,R1】和【L1,R】组成,那么,【L,R1】中啊a[index]的qz2=(R1-L+1)-(index-L),那么,【L,R】求和时其中的【L,R1】的a[index]的qz,和【L,R1】求和时a[index]的前缀,的差为qz1-qz2=R-R1;sum1[L,R1]=sum2[L,R1]+(R-R1)*(a[L]+a[L+1]+......a[R1]); 同理,

sum1[L1,R]=sum2[L1,R]+(R-R)*(a[L]+a[L+1]+......a[R1])=sum2[L1,R]+(R-R);

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const ll MAX=1e5+10;
struct node
{
    int l;
    int r;
    ll val;//保存根据公式求和的值;
    ll sum;//保存a[1]+a[2]+a[3]+...的值;

}tree[4*MAX];
ll a[MAX];
ll n,q;
void pushUp(ll root)
{
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
    tree[root].sum=tree[root*2].sum+(tree[root].r-tree[root*2].r)*tree[root*2].val+tree[root*2+1].sum;
}
void build(ll root,ll L,ll R)
{
    tree[root].l=L;
    tree[root].r=R;
    if(L==R)
    {
        tree[root].val=a[L];
        tree[root].sum=a[L];
        return ;
    }
    ll mid=(L+R)/2;
    build(root*2,L,mid);
    build(root*2+1,mid+1,R);
    pushUp(root);
    return;
}
void updateone(ll root,ll index,ll addval)
{
    if(tree[root].l==tree[root].r)
    {
        tree[root].val=addval;
        tree[root].sum=addval;
        return ;
    }
    ll mid=(tree[root].l+tree[root].r)/2;
    if(index<=mid)updateone(root*2,index,addval);
    else updateone(root*2+1,index,addval);
    //tree[root].sum+=(1+tree[root].r-index)*(addval-a[index]);
    //tree[root].val+=(addval-a[index]);
    pushUp(root);
    return ;
}
ll query(ll root,ll L,ll R)
{
    if(L<=tree[root].l&&tree[root].r<=R)
    {
        return tree[root].sum+(R-tree[root].r)*tree[root].val;
    }

    ll mid=(tree[root].l+tree[root].r)/2;
    ll ans=0;
    if(L<=mid)ans+=query(root*2,L,R);
    if(R>mid)ans+=query(root*2+1,L,R);
    return ans;
}
int main()
{
        scanf("%lld%lld",&n,&q);
        for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
        build(1,1,n);
        while(q--)
        {
            ll op,b;
            ll c;
            scanf("%lld%lld%lld",&op,&b,&c);
            if(op==1)
                printf("%lld\n",query(1,b,c));
            else if(op==2)
            {
                updateone(1,b,c);
            }

        }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37378303/article/details/82624058