赞
踩
给定长度为N的数列A,然后输入M行操作指令。
第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。
第二类指令形如“Q X”,表示询问数列中第x个数的值。
对于每个询问,输出一个整数表示答案。
输入格式
第一行包含两个整数N和M。
第二行包含N个整数A[i]。
接下来M行表示M条指令,每条指令的格式如题目描述所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
数据范围
1≤N,M≤105
,
|d|≤10000,
|A[i]|≤1000000000
样例
输入样例:
10 5
1 2 3 4 5 6 7 8 9 10
Q 4
Q 1
Q 2
C 1 6 3
Q 2
输出样例:
4
1
2
5
这道题主要是通过树状数组的单点查询和区间增加来实现,
首先我们新建一个树状数组b,然后初值为0,开始读取每条指令,如果是clrd指令,我们就先把b[l]+d,然后把b[r+1]-d;这样就实现了在区间lr中增加d的操作,这主要是运用的分差求前缀和的思想,我们现在的数组b就好比一个分差数组,而对分差数组求前缀和,得到的就是对某个区间的操作数的变化。然后我们再加上原先的a[i]值就可以求出我们的数组值
#include<iostream> using namespace std; const int N=1e5+10; int a[N],c[N]; int n; inline int lowbit(int x) { return (-x)&x; } inline int ask(int x) { int ans=a[x]; for(;x;x-=lowbit(x)); ans+=c[x]; return ans; } inline void add(int x,int y) { for(;x<=n;x+=lowbit(x)) c[x]+=y; } int main() { int m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; getchar(); while(m--) { char ch; cin>>ch; if(ch=='C'){ int x, y,z; cin>>x>>y>>z; add(x,z); add(y+1,-z); } else if(ch=='Q') { int k; cin>>k; printf("%d\n",ask(k)); } } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。