Fork me on github

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

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]×(L1)++a[r1]×2+a[r] (LL is the length of [ ll, rr ] that equals to r - l + 1rl+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

 

posted @ 2018-09-09 22:48  acboyty  阅读(300)  评论(0编辑  收藏  举报