当前位置:   article > 正文

一个简单的整数问题_第一行:输入两个数 n,q,表示给定数组的长度和操作数 第二行:输入n个数,表示长度为

第一行:输入两个数 n,q,表示给定数组的长度和操作数 第二行:输入n个数,表示长度为

给定长度为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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/998626
推荐阅读
相关标签
  

闽ICP备14008679号