AcWing 242. 一个简单的整数问题
Posted acmloser
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 242. 一个简单的整数问题相关的知识,希望对你有一定的参考价值。
考察:树状数组
确实简单....就是差分+树状数组即可.本蒟蒻还以为又有什么神乎其神的优化.....
思路:
我们先看第一个指令:第一类指令形如 C l r d
,表示把数列中第 l∼r 个数都加 d。
l~r区间内+d .单看这个操作容易想到差分. 即 修改b[l]与b[r+1]
再看第二个指令:第二类指令形如 Q x
,表示询问数列中第 x 个数的值。
配合上一个指令的差分数组.这里如果考虑差分就是求x的前缀和.
我们综合来看,修改b数组两个单点的值,求x的前缀和.这正好对应树状数组的操作.因此可以用树状数组优化时间复杂度.
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 typedef long long LL; 5 const int N = 100010; 6 LL b[N],m,n,tr[N]; 7 char s[2]; 8 void insert(int l,int r,int x) 9 { 10 b[l]+=x,b[r+1]-=x; 11 } 12 int lowbit(int x) 13 { 14 return x&-x; 15 } 16 void add(int k,int x) 17 { 18 for(int i=k;i<=n;i+=lowbit(i)) tr[i]+=x; 19 } 20 LL ask(int x) 21 { 22 LL ans = 0; 23 for(int i=x;i;i-=lowbit(i)) ans+=tr[i]; 24 return ans; 25 } 26 int main() 27 { 28 scanf("%d%d",&n,&m); 29 for(int i=1;i<=n;i++) 30 { 31 int x; scanf("%d",&x); 32 insert(i,i,x); 33 } 34 for(int i=1;i<=n;i++) add(i,b[i]); 35 while(m--) 36 { 37 int l,r,x; 38 scanf("%s%d",s,&l); 39 if(s[0]==\'Q\') {printf("%lld\\n",ask(l));continue;} 40 scanf("%d%d",&r,&x); 41 add(l,x); add(r+1,-x); 42 } 43 return 0; 44 }
以上是关于AcWing 242. 一个简单的整数问题的主要内容,如果未能解决你的问题,请参考以下文章
AcWing 242 一个简单整数问题(区间修改 单点查询)