洛谷P3368 【模板】树状数组 2 题解
题目描述
如题,已知一个数列,你需要进行下面两种操作:
-
将某区间每一个数数加上 x;
-
求出某一个数的值。
输入格式
第一行包含两个整数 N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含 N 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 M 行每行包含 2 或 4个整数,表示一个操作,具体如下:
操作 1: 格式:1 x y k 含义:将区间 [x,y] 内每个数加上 k;
操作 2: 格式:2 x 含义:输出第 x 个数的值。
输出格式
输出包含若干行整数,即为所有操作 2 的结果。
AC代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 5 ll n,m,c[5000001]; 6 7 ll lowbit(ll x) 8 { 9 return x&(-x); 10 } 11 12 void change(ll k,ll v) 13 { 14 while (k<=n) 15 { 16 c[k]+=v; 17 k+=lowbit(k); 18 } 19 } 20 21 void change_range(ll l,ll r,ll t) 22 { 23 change(l,t); 24 change(r+1,-t); 25 } 26 27 ll getsum(ll k) 28 { 29 int ans=0; 30 while (k>0) 31 { 32 ans+=c[k]; 33 k-=lowbit(k); 34 } 35 return ans; 36 } 37 38 int main() 39 { 40 scanf("%lld%lld",&n,&m); 41 ll t; 42 for (int i=1;i<=n;i++) 43 { 44 scanf("%lld",&t); 45 change_range(i,i,t); 46 } 47 while (m--) 48 { 49 ll op,x,y,k; 50 scanf("%lld",&op); 51 if (op==1) 52 { 53 scanf("%lld%lld%lld",&x,&y,&k); 54 change_range(x,y,k); 55 } 56 if (op==2) 57 { 58 scanf("%lld",&x); 59 cout<<getsum(x)<<endl; 60 } 61 } 62 return 0; 63 }

浙公网安备 33010602011771号