CODEVS 1080 线段树练习 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CODEVS 1080 线段树练习 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:http://codevs.cn/problem/1080/

题目描述 Description

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

输入描述 Input Description

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

输出描述 Output Description

共m行,每个整数

样例输入 Sample Input

6

3

4

1 3 5

2 1 4

1 1 9

2 2 6

样例输出 Sample Output

22

22

数据范围及提示 Data Size & Hint

1≤N≤100000, m≤10000 。

 

分析:

这是一个板子题...

 

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 
 6 const int MAXN = 100000 + 5;
 7 
 8 int sdata[MAXN<<2],num[MAXN];
 9 
10 inline void read(int &x)
11 {
12     char ch = getchar(),c = ch;x = 0;
13     while(ch < 0 || ch > 9) c = ch,ch = getchar();
14     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
15     if(c == -) x = -x;
16 }
17 
18 inline void update(int o)
19 {
20     sdata[o] = sdata[o<<1]+sdata[o<<1|1];
21 }
22 
23 void build(int l,int r,int o)
24 {
25     if(l == r)
26     {
27         sdata[o] = num[l];
28         return;
29     }
30     int mid = (l+r)>>1;
31     build(l,mid,o<<1);
32     build(mid+1,r,o<<1|1);
33     update(o);
34 }
35 
36 void modify(int l,int r,int o,int p,int k)
37 {
38     if(l == r && r == p)
39     {
40         sdata[o] += k;
41         return;
42     }
43     int mid = (l+r)>>1;
44     if(p > mid) modify(mid+1,r,o<<1|1,p,k);
45     else modify(l,mid,o<<1,p,k);
46     update(o);
47 }
48 
49 int ask(int l,int r,int o,int ll,int rr)
50 {
51     if(ll <= l && rr >= r)
52     {
53         return sdata[o];
54     }
55     int mid = (l+r)>>1;
56     int ans = 0;
57     if(ll <= mid) ans += ask(l,mid,o<<1,ll,rr);
58     if(rr > mid) ans += ask(mid+1,r,o<<1|1,ll,rr);
59     return ans;
60 }
61 
62 int m,n,a,b,op;
63 
64 int main()
65 {
66     read(n);
67     for(register int i = 1;i <= n;++ i)
68         read(num[i]);
69     build(1,n,1);
70     read(m);
71     for(register int i = 1;i <= m;++ i)
72     {
73         read(op),read(a),read(b);
74         if(op == 1)
75             modify(1,n,1,a,b);
76         else
77             printf("%d\n",ask(1,n,1,a,b));
78     }
79     return 0;
80 } 

 

以上是关于CODEVS 1080 线段树练习 题解的主要内容,如果未能解决你的问题,请参考以下文章

codevs1080线段树练习

[Codevs] 1080 线段树练习

codevs 1080 线段树练习

1080 线段树练习 (codevs)

codevs 1080 线段树练习--用树状数组做的

CODEVS 1081 线段树练习 2 题解