zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Activiti 教程
    head插件对elasticsearch 索引文档的增删改查
    ElasticSearch的基本用法与集群搭建
    kibana查询语法
    Elasticsearch: 权威指南(官方教程)
    ElasticSearch安装及简单配置说明
    在Linux上安装Elasticsearch5.x
    在Windows上安装Elasticsearch 5.x
    SVN提交出错--URL access forbidden for unknown reason
    Elasticsearch配置详解、文档元数据
  • 原文地址:https://www.cnblogs.com/rainydays/p/2777685.html
Copyright © 2011-2022 走看看