AcWing242一个简单的整数问题1(差分+树状数组)

题目地址https://www.acwing.com/problem/content/248/

题目描述

 

给定长度为N的数列A,然后输入M行操作指令。

 

第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。

 

第二类指令形如“Q X”,表示询问数列中第x个数的值。

 

对于每个询问,输出一个整数表示答案。

 

输入格式

 

第一行包含两个整数N和M。

 

第二行包含N个整数A[i]。

 

接下来M行表示M条指令,每条指令的格式如题目描述所示。

 

输出格式

 

对于每个询问,输出一个整数表示答案。

 

每个答案占一行。

 

数据范围

 

1N,M1e5
|d|10000,
|A[i]|1000000000

题解:树状数组可以额解决的是单点修改和区间求和问题。这道题是区间修改和单点求值。那么就需要和差分数组来一起进行。差分数组是在原先的数组a的基础上进行差分的,差分数组b[i]=a[i]-a[i]-1,所以区间[l,r]修改就相当于b[l]+=d,b[r+1]-=d,单点求值就是对差分数组进行前缀和求值

AC代码

#include<iostream>
using namespace std;
const int N=1e5+10;
#define ll long long int
#define lowbit(x)  (x&-(x))
ll c[N]={0},n,m,a[N]={0};

void add(int x,ll d){
    while(x<=n){
        c[x]+=d;
        x+=lowbit(x);
    }
} 

ll sum(int x){
    ll sum=0;
    while(x>0){
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}

int main(){
    cin>>n>>m;
    ll now=0,x;
    for(int i=1;i<=n;i++){
        cin>>x;
        a[i]=x-now;
        now=x;
    }
    for(int i=1;i<=n;i++) add(i,a[i]);
    char ch;
    ll l,r,d;
    while(m--){
        cin>>ch;
        if(ch=='C'){
            cin>>l>>r>>d;
            add(l,d);
            add(r+1,-d); 
        }
        else {
            cin>>x;
            cout<<sum(x)<<endl;
        }
    }
    return 0;
}

写于:202/8/26 13:03

 

posted @ 2020-08-26 13:04  白菜茄子  阅读(153)  评论(0编辑  收藏  举报