1. 程式人生 > >ACM-ICPC 2018 徐州賽區網路預賽 徐州 H Ryuji doesn't want to study 線段樹

ACM-ICPC 2018 徐州賽區網路預賽 徐州 H 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:

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

222. 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 a[i](a[i]≤1e9)a[i]( a[i] \le 1e9)a[i](a[i]≤1e9) .

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

題目來源

將a[i]*(r-i+1)化成a[i]*(r+1)-a[i] 然後建兩個二叉樹, 一個維護區間和, 一個維護字首區間和。

程式碼如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=100005;
long long int a[maxn];
long long int t1[maxn<<2];
long long int t2[maxn<<2];
int n,q;
void pushup (int re,long long int* t)
{
    t[re]=t[re<<1]+t[re<<1|1];
}
void build1 (int l,int r,int re,long long int* t)
{
    if(l==r)
    {
        t[re]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build1 (l,mid,re<<1,t);
    build1 (mid+1,r,re<<1|1,t);
    pushup (re,t);
}
void build2 (int l,int r,int re,long long int* t)
{
    if(l==r)
    {
        t[re]=a[l]*l;
        return;
    }
    int mid=(l+r)>>1;
    build2 (l,mid,re<<1,t);
    build2 (mid+1,r,re<<1|1,t);
    pushup (re,t);
}
void update1 (int l,int r,int re,int loc,long long int data,long long int* t)
{
    if(l==r)
    {
        t[re]=data;
        return;
    }
    int mid=(l+r)>>1;
    if(mid>=loc)
        update1 (l,mid,re<<1,loc,data,t);
    else
        update1 (mid+1,r,re<<1|1,loc,data,t);
    pushup(re,t);
}
void update2 (int l,int r,int re,int loc,long long int data,long long int* t)
{
    if(l==r)
    {
        t[re]=data*l;
        return;
    }
    int mid=(l+r)>>1;
    if(mid>=loc)
        update2 (l,mid,re<<1,loc,data,t);
    else
        update2 (mid+1,r,re<<1|1,loc,data,t);
    pushup(re,t);
}
long long int query (int l,int r,int re,int left,int right,long long int* t)
{
     if(l>=left&&r<=right)
        return t[re];
     long long int ans=0;
     int mid=(l+r)>>1;
     if(mid>=left)
        ans+=query (l,mid,re<<1,left,right,t);
     if(mid<right)
        ans+=query (mid+1,r,re<<1|1,left,right,t);
     return ans;
}
int main()
{
    scanf("%d%d",&n,&q);
    for (int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    build1 (1,n,1,t1);
    build2 (1,n,1,t2);
    while (q--)
    {
        int op;
        long long int x,y;
        scanf("%d%lld%lld",&op,&x,&y);
        if(op==1)
        {
            long long int sum=(y+1)*query(1,n,1,x,y,t1)-query(1,n,1,x,y,t2);
            printf("%lld\n",sum);
        }
        else
        {
           update1(1,n,1,x,y,t1);
           update2(1,n,1,x,y,t2);
        }
    }
    return 0;
}