树状数组之 ——区间更新,单点查询;区间更新,区间查询;

//修改区间,查询点
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100005;
const int maxq=100005;
int a[maxn];int b[maxn];int c[maxn];
//a原数组,b是a的差分数组,c是b的树状数组
int lowbit(int x){
    return x&(-x);
}
int n,q;
void c_update(int x,int y){
    for(;x<=n;x+=lowbit(x)) c[x]+=y;
}
void update(int x,int y,int z){
    b[x]+=z;
    b[y+1]-=z;
    c_update(x,z);
    c_update(y+1,-z);
}
int sum(int x)
{
    int ans=0;
    for(;x>0;x-=lowbit(x))
        ans+=c[x];
    return ans;
}
int main()
{
    int x,y;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    b[1]=a[1];
    c_update(1,b[1]);
    for(int i=2;i<=n;i++){
        b[i]=a[i]-a[i-1];
        c_update(i,b[i]);
    }
    cin>>q;
    while(q--){
        cin>>x;
        if(x==1){
            int y,z,w;
            cin>>y>>z>>w;
            update(y,z,w);
        }
        if(x==2){
            cin>>y;
            cout<<sum(y)<<endl;
        }
    }
    return 0;
}
//修改区间,区间查询
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=200005,maxq=200005;
int n,q;
int lowbit(int x){
    return x&(-x);
}
long long delta[maxn]; //差分数组
long long deltai[maxn]; //delta*i
long long sum[maxn];//原始前缀和
void update(long long *c,int x,int y)
{
    for(;x<=n;x+=lowbit(x))
        c[x]+=y;
}
long long query(long long *c,int x)
{
    long long ans=0;
    while(x>0)
    {
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    int x;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        sum[i]=sum[i-1]+x;
    }
    cin>>q;
    while(q--)
    {
        cin>>x;
        if(x==1)//区间更新
        {
            int y,z,w;
            cin>>y>>z>>w;
            update(delta,y,w);
            update(delta,z+1,-w);
            update(deltai,y,w*y);
            update(deltai,z+1,-w*(z+1));
        }
        if(x==2)//区间求和
        {
            int y,z;
            cin>>y>>z;
            long long suml=sum[y-1]+y*query(delta,y-1)-query(deltai,y-1);
            long long sumr=sum[z]+(z+1)*query(delta,z)-query(deltai,z);
            cout<<sumr-suml<<endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/qie-wei/p/10160172.html