数据结构---树状数组


#include<bits/stdc++.h>

using namespace std;
const int maxn = 10000;
int arr[maxn];
int bit[maxn];
int n, q;

int lowbit(int r) {//获得二进制中最后一个1
    return r & (-r);
}

void add(int i, int x) {
    while(i <= n) {
        bit[i] += x;
        i += lowbit(i);
    }
}

int query(int i) {//求前i项的和
    int sum = 0;
    while(i > 0) {
        sum += bit[i];
        i -= lowbit(i);
    }
    return sum;
}

void update(int l, int r, int x) {//更新,原理是树状数组的单点更新
    for(int i = l; i <= r; i++) {
        add(i, x);
    }
}

int main() {
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> arr[i];
        add(i,arr[i]);
    }
    cin >> q;
    int l, r, k;
    string s;
    while(q--) {
        cin >> s >> l >> r;
        if(s == "query")cout << query(r) - query(l - 1) << endl;
        else {
            cin >> k;
            update(l, r, k);
        }
    }
    /*for(int i = 1; i <= n; i++) {
        cout << arr[i] << " ";
    }cout << endl;
    for(int i = 1; i <= n; i++) {
        cout << bit[i] << " ";
    }cout << endl;*/
    return 0;
}

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 200100;
ll a[maxn];
ll c1[maxn],c2[maxn];
ll sum[maxn];
int n,m;
char ch[5];

ll lowbit(ll x){
    return x&(-x);
}

void update(ll arry[],int i,ll x){
    while(i <= n){
        arry[i] += x;
        i += lowbit(i);
    }
}
ll query(ll arry[],int x)
{
    ll cnt=0;
    while(x>0)
    {
        cnt+=arry[x];
        x-=lowbit(x);
    }
    return cnt;
}

int main(){
    ll ans;
    while(scanf("%d%d",&n,&m)==2){
        memset(sum,0,sizeof(sum));
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        int l,r;
        ll t;
        while(m--){
            scanf("%s",ch);
            if(ch[0]=='Q'){
                scanf("%d%d",&l,&r);
                ans=sum[r]-sum[l-1];
                ans+=(r+1)*query(c1,r)-query(c2,r);
                ans-=l*query(c1,l-1)-query(c2,l-1);
                printf("%lld\n",ans);
            }
            if(ch[0]=='C'){
                scanf("%d%d%lld",&l,&r,&t);
                update(c1,l,t);
                update(c1,r+1,-t);
                update(c2,l,l*t);
                update(c2,r+1,-(r+1)*t);
            }
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值