Codevs1081 线段树练习 2
题目描述 Description
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 3
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
数据范围
1<=n<=100000
1<=q<=100000
树状数组:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 6 int n,m; 7 int f[100001]; 8 9 int read() 10 { 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 17 int lowbit(int x) 18 { 19 return x&(-x); 20 } 21 22 void update(int x,int num) 23 { 24 while(x<=n) 25 { 26 f[x]+=num; 27 x+=lowbit(x); 28 } 29 } 30 31 int sum(int x) 32 { 33 int sum=0; 34 while(x>0) 35 { 36 sum+=f[x]; 37 x-=lowbit(x); 38 } 39 return sum; 40 } 41 42 int main() 43 { 44 n=read(); 45 for(int i=1;i<=n;i++) 46 update(i,read()); 47 m=read(); 48 for(int i=1;i<=m;i++) 49 { 50 int t=read(),x,y,z; 51 if(t==1) 52 { 53 x=read();y=read();z=read(); 54 for(int j=x;j<=y;j++) 55 update(j,z); 56 } 57 if(t==2) 58 { 59 x=read(); 60 printf("%d\n",sum(x)-sum(x-1)); 61 } 62 } 63 return 0; 64 }