给定数组arr[] ={1,3,7,5,2}
经过区间加减后求arr数组中的元素
如题,已知一个数列,你需要进行下面两种操作:
将某区间每一个数加上 xx;
求出某一个数的值。
第一行包含两个整数 NN、MM,分别表示该数列数字的个数和操作的总个数。
第二行包含 NN 个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。
接下来 MM 行每行包含 22 或 44个整数,表示一个操作,具体如下:
操作 11: 格式:1 x y k
含义:将区间 [x,y][x,y] 内每个数加上 kk;
操作 22: 格式:2 x
含义:输出第 xx 个数的值。
输出包含若干行整数,即为所有操作 22 的结果。
输入 #1
5 5 1 5 4 2 3 1 2 4 2 2 3 1 1 5 -1 1 3 5 7 2 4
输出 #1
6 10
样例 1 解释:
故输出结果为 6、10。
数据规模与约定
对于 100% 的数据:1 <=N, M<= 500000,1≤x,y≤n,保证任意时刻序列中任意元素的绝对值都不大于 2^{30}。
结合树状数组模板题:【模板】树状数组 2 - 洛谷
- #include
- #include
- using namespace std;
- #define lowbit(x) ((-x)&(x))
- const int inf = 500010;
- int n , m ;
- int tree[inf] , ans[inf] , arr[inf];
-
- void add(int i , int k)
- {
- for(;i<=n;i+=lowbit(i))
- tree[i]+=k;
- }
-
- int sum(int i)
- {
- int ans = 0;
- for(;i>0;i-=lowbit(i))
- ans+=tree[i];
- return ans;
- }
-
- int main()
- {
- ios::sync_with_stdio(false);
- cin>>n>>m;
- for(int i=1;i<=n;i++)
- {
- cin>>arr[i];
- add(i,arr[i]-arr[i-1]); //arr就是d数组
- }
- for(int i=0;i
- {
- int tmp , x , y , k;
- cin>>tmp;
- if(tmp==1)
- {
- cin>>x>>y>>k;
- add(x,k);//差分标记
- add(y+1,-k);
- }else{
- cin>>x;
- cout<<sum(x)<
//求前缀和得出元素的值 - }
- }
- return 0;
- }