树状数组模板1

今天给大家分享一下树状数组。

题目:

给出一个有n个元素的整数数组A,(1<=n<=100000) 有m(1<=m<=100000)个命令,这些命令有两种形式:(1) C i j,表示将元素a[i]的值修改为整数j (2) Q i,表示求前缀和Si=A1+A2+…+Ai的值。

输入格式:

包含m+2行: 第1行有二个整数n和m,以一个空格分隔。 第2行有n个整数,互相以空格分隔,表示初始时数组中的n个元素的值。 第3行开始至第m+2行中,第j+2行表示第j个命令 如果该行的第1个字符为大写字母C,则C后会有两个整数,每个整数前会有一个空格。 如果该行的第1个字符为大写字母Q,则Q后会有一个整数i,该整数前会有一个空格。

输出格式:只有一行,该行有若干个整数,每个整数表示要求输出的一个前缀和。 每个输出的前缀和之间互相以一个空格分隔,前后不能有多余空格。

输入样例:

3 2
1 2 3
C 1 10
Q 3

输出样例:

15

代码样例:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
using namespace std;
#pragma GCC optimize (3)
int n,m,us;
ll intm[100009],intn[100009];
void modify(int x,ll dx)
{
  intn[x]+=dx;
  intm[(x-1)/us+1]+=dx;
}
int query(int x)
{
  ll sum=0;
  for(int i=1;i<=(x-1)/us;i++)
  {
    sum+=intm[i];
  }
  for(int i=(x-1)/us*us+1;i<=x;i++)
  {
    sum+=intn[i];
  }
  return sum;
}
int main()
{
  scanf("%d%d",&n,&m);
  us=sqrt(n);
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&intn[i]);
    intm[(i-1)/us+1]+=intn[i];
  }
  char k[2];
  int x,y;
  for(int i=1;i<=m;i++)
  {
    scanf("%s",k);
    if(k[0]=='C')
    {
      scanf("%d%d",&x,&y);
      modify(x,y-intn[x]);
    }
    else if(k[0]=='Q')
    {
      scanf("%d",&x);
      ll sum=query(x);
      printf("%lld\n",sum); 
    }
  }
  return 0;
}//代码仅供参考,请勿转载。
//wangmy

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值