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

ACM-ICPC 2018 徐州賽區網絡預賽 H. Ryuji doesn't want to study (線段樹)

ace esp repr for lin n) mat put 鏈接

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 100000q100000).

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
5

題目鏈接:

https://nanti.jisuanke.com/t/31460

題目大意:

給你一個數列a[1..n],多次求對於[i..j]區間,a[i]*L+a[i+1]*(L-1)+...+a[j]*1,其中L是區間長度(j-i+1)。

線段樹水題。

對該數列建立線段樹。每個節點維護兩個值sum和tri。sum是區間和,tri是區間三角和(即題目中所要求的和)。適當地改動一下操作,就是一個簡單的單點修改,區間查詢的線段樹問題。

由於是在區域賽預賽中做出來的,還是寫個博客紀念一下吧。^_^

技術分享圖片
#include<cstdio>
#include<cmath>

using namespace std;

const int maxn=100000;

struct ttree
{
    int l,r;
    long long sum;
    long long tri;
};
ttree tree[maxn*4+10];

void pushup(int x)
{
    if(tree[x].l==tree[x].r)
        return;
    tree[x].sum=tree[x*2].sum+tree[x*2+1].sum;
    tree[x].tri=tree[x*2].tri+tree[x*2+1].tri+
                tree[x*2].sum*(tree[x*2+1].r-tree[x*2+1].l+1);
}

void build(int x,int l,int r)
{
    tree[x].l=l;
    tree[x].r=r;
    if(l==r)
    {
        scanf("%lld",&tree[x].sum);
        tree[x].tri=tree[x].sum;
    }
    else
    {
        int mid=(l+r)/2;
        build(x*2,l,mid);
        build(x*2+1,mid+1,r);
        pushup(x);
    }
}

void modify(int x,int pos,int val)
{
    if(tree[x].l==tree[x].r)
    {
        tree[x].sum=tree[x].tri=val;
        return;
    }
    int mid=(tree[x].l+tree[x].r)/2;
    if(pos<=mid)
        modify(x*2,pos,val);
    else
        modify(x*2+1,pos,val);
    pushup(x);
}

long long query(int x,int l,int r)
{
    if(l<=tree[x].l&&r>=tree[x].r)
        return tree[x].sum*(r-tree[x].r)+tree[x].tri;
    long long ret=0;
    int mid=(tree[x].l+tree[x].r)/2;
    if(l<=mid)
        ret+=query(x*2,l,r);
    if(r>mid)
        ret+=query(x*2+1,l,r);
    return ret;
}

int main()
{
    int n,q;
    scanf("%d%d",&n,&q);
    build(1,1,n);
    int a,b,c;
    while(q--)
    {
        scanf("%d%d%d",&a,&b,&c);
        if(a==1)
        {
            printf("%lld\n",query(1,b,c));
        }
        else
        {
            modify(1,b,c);
        }
    }
    return 0;
}
View Code

ACM-ICPC 2018 徐州賽區網絡預賽 H. Ryuji doesn't want to study (線段樹)