zoukankan      html  css  js  c++  java
  • 树状数组(区间修改,区间查询 )

    首先还是先利用区间修改 单点查询用过的差分思想(将区间的修改操作变成单点的修改),我们先搞一个c数组作为差分数组

      a数组是原数组,c数组是差分数组。

    简单可证:

    a[1] = c[1] ,  a[2] = c[2] + c[1],  a[3] = c[3] + c[2] + c[1],……;

    那么可以得到以下式子:

    a[1]+a[2]+...+a[i]

    =c[1] + ( c[1] + c[2] ) + ... + ( c[1] + c[2] + ... + c[i] )

    =i*c[1]+(i-1)*c[2]+...+c[i]

    =i *(c[1]+c[2]+...+c[i])-1*c[2]-...-(i-1)*c[i]

    于是,我们再搞一个数组d=(i-1)*c[i]

    那之前的式子就可以表示为

    a[1]+a[2]+…+a[i]=i*(c[1]+c[2]+...+c[i])-(d[1]+d[2]+...+d[i]);

    #include<iostream>
    #include<cstdio> 
    using namespace std;
    
    long long n,m;
    long long a[500009]; 
    long long c[500009],d[500009];
    long long lowbit(long long x)
    {
        return (x&(-x));
    }
    void change(long long *e,long long x,long long k)
    {
        for(int i=x;i<=n;i+=lowbit(i))
        {
            e[i]+=k;
        }
    }
    long long query(long long *e,long long x)
    {
        long long sum=0;
        for(int i=x;i>=1;i-=lowbit(i))
        {
            sum+=e[i];
        }
        return sum;
    }
    inline long long read()
    {
        long long x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*f;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
            change(c,i,a[i]-a[i-1]);
            change(d,i,(long long)(i-1)*(a[i]-a[i-1]));
        }
        for(int i=1;i<=m;i++)
        {
            long long p;
            cin>>p;
            if(p==1)//修改 
            {
                long long r,l,v;
                cin>>l>>r>>v;
                change(c,l,v);
                change(c,r+1,-v);
                change(d,l,(long long)(l-1)*v);
                change(d,r+1,(long long)-r*v);
            }
            if(p==2)//统计 
            {
                long long r,l;
                cin>>l>>r;
                long long t1=query(c,l-1)*(l-1)-query(d,l-1);
                long long t2=query(c,r)*r-query(d,r);
                printf("%lld
    ",t2-t1);
            }
        }
        return 0;
    }
    /*
    5 2
    1 7 6 5 8
    1 2 3 1//修改【2~3】+1 
    2 2 4//查询2~4 
    */
  • 相关阅读:
    hdu acm 2844 Coins 解题报告
    hdu 1963 Investment 解题报告
    codeforces 454B. Little Pony and Sort by Shift 解题报告
    广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
    hdu acm 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    hdu acm 1114 Piggy-Bank 解题报告
    poj 2531 Network Saboteur 解题报告
    数据库范式
    ngnix 配置CI框架 与 CI的简单使用
    Vundle的安装
  • 原文地址:https://www.cnblogs.com/1129-tangqiyuan/p/11221329.html
Copyright © 2011-2022 走看看