码迷,mamicode.com
首页 > 其他好文 > 详细

线段树练习(单点增减)

时间:2016-07-22 12:38:52      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:

CODEVS 1080 线段树练习

题目描述

一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。

输入描述

输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

输出描述

共m行,每个整数。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 long long sum[400000+10];
 5 int n,m;
 6 int ql,qr;
 7 long long query(int o,int L,int R){
 8     int M=L+(R-L)/2;
 9     long long ans=0;
10     if(ql<=L&&R<=qr) return sum[o];
11     if(ql<=M) ans+=query(2*o,L,M);
12     if(M<qr) ans+=query(2*o+1,M+1,R);
13     return ans;
14 }
15 int p,v;
16 void update(int o,int L,int R){
17     int M=L+(R-L)/2;
18     if(L==R) sum[o]+=v;
19     else{
20         if(p<=M) update(2*o,L,M); else update(2*o+1,M+1,R);
21         sum[o]=sum[2*o]+sum[2*o+1];
22     }
23 }
24 int main()
25 {
26     cin>>n;
27     memset(sum,0,sizeof(sum));
28     for(int i=1;i<=n;i++){
29         cin>>v;
30         p=i;
31         update(1,1,n);
32     }
33     cin>>m;
34     int op,a,b;
35     for(int i=1;i<=m;i++){
36         cin>>op>>a>>b;
37         if(op==1){
38             p=a,v=b;
39             update(1,1,n);
40         }else{
41             ql=a,qr=b;
42             cout<<query(1,1,n)<<endl;
43         }
44     }    
45     return 0;
46 }

 

线段树练习(单点增减)

标签:

原文地址:http://www.cnblogs.com/gzhonghui/p/5694607.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!