zoukankan      html  css  js  c++  java
  • 树状数组之区间更新与查询

    具体思路:由于树状数组裸的模板只能通过数组求区间和,而对于区间的更新的查询无法实现,所以通过多个数组进行辅助。

    具体公式,通过三个数组实现。第一个数组记录第一组的前缀和。然后如果是更新的话,举个例子,一共有10个数,1~n.在5 8 之间每一个数加3,也就是总的和在原来的基础上上加上了12,我们可以这样记录,从第5个到最后一个都加上3,然后从的第九个到最后一个都减去3.这样就记录好了。具体实现这个操作的可以通过一个数组arr实现。arr[i]记录的是从第i个数到最后一个数变化了多少。

    sum(l,r)=a[r]-a[l-1]+arr[i]*(r+1)+i*arr[i]   (l  < = i < = r),然后再开两个数组记录arr[i]和i*arr[i]的前缀和就可以了。然后计算的时候按照前缀和的做法就行了,然后按照公式来就行了。

    题目链接:

    https://vjudge.net/contest/66989#problem/C

    AC代码(有时间具体解释):

    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stdio.h>
    using namespace std;
    # define inf 0x3f3f3f3f
    # define maxn 100000+100
    # define ll long long
    ll ans[maxn];
    ll ansi[maxn];
    ll s[maxn];
    ll n,m;
    
    ll lowbit(ll t)
    {
        return t&(-t);
    }
    void update(ll t1,ll t2,ll *t)
    {
        while(t1<=n)
        {
            t[t1]+=t2;
            t1+=lowbit(t1);
        }
    }
    ll sum(ll t1,ll *t)
    {
        ll ans=0;
        while(t1>=1)
        {
            ans+=t[t1];
            t1-=lowbit(t1);
        }
        return ans;
    
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        memset(s,0,sizeof(s));
        memset(ans,0,sizeof(ans));
        memset(ansi,0,sizeof(ansi));
        for(int i=1; i<=n; i++)
        {
            scanf("%lld",&s[i]);
            s[i]+=s[i-1];
        }
        char str[10];
        ll t1,t2,t3;
        while(m--)
        {
            scanf("%s",str);
            if(str[0]=='Q')
            {
                scanf("%lld%lld",&t1,&t2);
                printf("%lld
    ",s[t2]-s[t1-1]+(t2+1)*sum(t2,ans)-t1*sum(t1-1,ans)-(sum(t2,ansi)-sum(t1-1,ansi)));
            }
            else if(str[0]=='C')
            {
                scanf("%lld%lld%lld",&t1,&t2,&t3);
                update(t1,t3,ans);
                update(t2+1,-t3,ans);
                update(t1,t1*t3,ansi);
                update(t2+1,-(t2+1)*t3,ansi);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Moo.fx 超级轻量级的 javascript 特效库
    Oracle 异常错误处理
    变被动为主动
    数据结构定义
    Redis 一个keyvalue存储系统 简介
    使用Container.ItemIndex获取Repeater、Gridview行的序号的简单方法
    ORACLE SQL:经典查询练手第一篇
    MongoDB 一个基于分布式文件存储的数据库
    dojo Quick Start/dojo入门手册面向对象,定义Class
    面向过程分析与面向对象分析之间的区别
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262858.html
Copyright © 2011-2022 走看看