题目地址: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条指令,每条指令的格式如题目描述所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
数据范围
1≤N,M≤1e5
|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