zoukankan      html  css  js  c++  java
  • 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] imes L + a[l+1] imes (L-1) + cdots + a[r-1] imes 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
    ",query(1,b,c));
            }
            else
            {
                modify(1,b,c);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    vi 整行 多行 复制与粘贴
    FPGA设计—UVM验证篇 Hello world
    武汉市最大的二手车市场
    vim 使用技巧
    CentOS 7下的软件安装方法及策略
    搜索插件:ack.vim
    Vim插件管理
    【一】 sched.h
    Android USB驱动源码分析(-)
    在Python中反向遍历序列(列表、字符串、元组等)的五种方式
  • 原文地址:https://www.cnblogs.com/acboyty/p/9615644.html
Copyright © 2011-2022 走看看