zoukankan      html  css  js  c++  java
  • POJ 3468 A Simple Problem with Integers 【树状数组】

    题目链接:http://poj.org/problem?id=3468

    题目大意:给出一组数组v[i],有两种操作,一种给出两个数a,b。要求输出v[a]到v[b]之间的和。还有一种给出三个数a,b,c,让v[a]到v[b]之间的数全都加上c。

    全然是树状数组可以实现的功能,可是假设就这样单纯的套用模板,做另外一种操作是更新每一个值,这种操作就有可能超时。

    换一种思路,既然另外一种操作是给某区间上的全部数加上同样的值,那么应该是可以简化的才对。

    如果数组sum[i]为原数组从v[1]到v[i]的和。数组c1[i]为更新之后,v[i]到v[n]的添加量。分析一下结果ans:

    a,b之间的和ans=sum[b]-sum[a-1]+c1[1]*x + c1[2]*(x-1) + c1[3]*(x-2)+...+c1[x]*1

    ans=sum[b]-sum[a-1]+segema(c1[i]*(x-i+1))

    ans=sum[b]-sum[a-1] + (x+1)*segma(c1[i]) - segma(c1[i]*i)

    令c2[i]=c1[i]*i;

    如此便能利用树状数组解出此题

    代码:

    #include <stdio.h>
    #define N 100001
    #define lowbit(i) ( i & (-i) )
    int n;
    __int64 v[N];
    __int64 c1[N];// 每一个C数组代表v[i-lowbit(i)+1]到v[i]之间的和
    __int64 c2[N];
    __int64 sum[N];
    
    void Updata(__int64 *array,__int64 i,__int64 a)
    {
        for(;i<=n;i+=lowbit(i))
            array[i]+=a;
    }
    __int64 Sumv(__int64 *array,__int64 i)   //求出数组v[1]到v[i]的和
    {
        __int64 result=0;
        while (i>=1)
        {
            result+=array[i];
            i-=lowbit(i);
        }
        return result;
    }
    int main()
    {
        __int64 q,i=0;
        __int64 ans=0;
        scanf("%I64d%I64d",&n,&q);
        for(i=1;i<=n;i++)
            scanf("%I64d",&v[i]);
        for(__int64 i=1;i<=n;i++)
            sum[i]=sum[i-1]+v[i];
        while(q--)
        {
            char ch[2];
            scanf("%s",ch);
            if(ch[0]=='Q')
            {
                __int64 s,t;
                scanf("%I64d%I64d",&s,&t);
                ans=sum[t]-sum[s-1];
                ans+=((t+1)*Sumv(c1,t)-Sumv(c2,t));
                ans-=(s*Sumv(c1,s-1)-Sumv(c2,s-1));
                printf("%I64d
    ",ans);
            }
            else
            {
                __int64 a,b,c;
                scanf("%I64d%I64d%I64d",&a,&b,&c);
                Updata(c1,a,c);
                Updata(c1,b+1,-c);
                Updata(c2,a,c*a);
                Updata(c2,b+1,-c*(b+1));
            }
        }
        return 0;
    }
    


  • 相关阅读:
    【Mesh R-CNN】论文翻译(原理部分)
    关于栈的学习记录
    css入门笔记
    前端学习之html基础知识归纳
    navigator url无法跳转跳转问题
    新手小白学会vim脚本配置
    Linux下实现两个变量之间传参
    [Apache Doris] Apache Doris 架构及代码目录解读
    [编程总结] 开源系统平台化建设思路
    论文阅读|PointRend: Image Segmentation as Rendering
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5350267.html
Copyright © 2011-2022 走看看