• poj3468


    题意:一个数列,每次操作可以是将某区间数字都加上一个相同的整数,也可以是询问一个区间中所有数字的和。(这里区间指的是数列中连续的若干个数)对每次询问给出结果。

    分析:线保留型线段树,线段树中每个节点有两个变量:增量与和,一个记录当前节点对应区间被整体增加了几,另一个记录该区间的真子区间被增加了之后的和是多少。(该区间数字当前和=和+增量×区间长度)

    修改时更新路线上不完整覆盖的节点的和变量以及恰好完整覆盖的节点的增量变量。询问可以通过回溯过程通过各节点两变量值求得。

    三种线段树,参见:http://www.cnblogs.com/rainydays/archive/2011/09/06/2169082.html

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    const    int        maxn = 100001;
    
    struct cnode
    {
        int        l, r;
        long long nsum, inc;
        cnode    *pleft, *pright;
    };
    
    int        n, q, ncount;
    cnode    tree[maxn * 3];
    
    void buildtree(cnode *proot, int s, int e)
    {
        proot->l = s;
        proot->r = e;
        proot->inc = 0;
        proot->nsum = 0;
        if (s != e)
        {
            ncount++;
            proot->pleft = tree + ncount;
            ncount++;
            proot->pright = tree + ncount;
            buildtree(proot->pleft, s, (s + e) / 2);
            buildtree(proot->pright, (s + e) / 2 + 1, e);
        }
    }
    
    void insert(cnode *proot, int s, int e, long long increase)
    {
        int        mid;
    
        if (s > proot->r || e < proot->l)
            return;
        s = max(s, proot->l);
        e = min(e, proot->r);
        mid = (proot->l + proot->r) / 2;
        if (s == proot->l && e == proot->r)
        {
            proot->inc += increase;
            return;
        }
        proot->nsum += (e - s + 1) * increase;
        insert(proot->pleft, s, e, increase);
        insert(proot->pright, s, e, increase);
    }
    
    long long query(cnode *proot, int s, int e)
    {
        int        mid;
    
        if (s > proot->r || e < proot->l)
            return 0;
        s = max(s, proot->l);
        e = min(e, proot->r);
        mid = (proot->l + proot->r) / 2;
        if (proot->l == s && proot->r == e)
            return proot->nsum + proot->inc * (proot->r - proot->l + 1);
        long long inc_value = proot->inc * (e - s + 1);
        return query(proot->pleft, s, e) + query(proot->pright, s, e) + inc_value;
    }
    
    int main()
    {
        int        i, h, s, e;
        char    ch;
    
        scanf("%d%d", &n, &q);
        ncount = 0;
        buildtree(tree, 1, n);
        for (i = 0; i < n; i++)
        {
            scanf("%d", &h);
            insert(tree, i + 1, i + 1, h);
        }
        for (i = 0; i < q; i++)
        {
            getchar();
            scanf("%c", &ch);
            if (ch == 'C')
            {
                scanf("%d%d%d", &s, &e, &h);
                insert(tree, s, e, h);
            }
            else
            {
                scanf("%d%d", &s, &e);
                printf("%lld\n", query(tree, s, e));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    flex布局
    redis持久化的四种方式
    list all index in elasticsearch
    Java Thread停止关闭
    关于线程的一些操作方法
    将redis key打印到文本
    spout和bolt
    java读取redis的timeout异常
    storm中,ack与fail
    好文要收藏(大数据)
  • 原文地址:https://www.cnblogs.com/rainydays/p/2777685.html
Copyright © 2020-2023  润新知