【CODEVS1080】线段树练习

Description

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

Input

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

Output

共m行,每个整数

Sample Input

6

3

4

1 3 5

2 1 4

1 1 9

2 2 6

Sample Output

22

22

HINT

1≤N≤100000, m≤10000 。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=100010;
 5 int tot=0;
 6 int a[100005];
 7 struct treetype
 8 {
 9     int Left,Right; //区间[Left,Right)
10     int lptr,rptr; //左右孩子指针
11     int sum; //区间和
12 }t[2*maxn];
13 void buildtree(int ll,int rr) //建树
14 {
15     int cur=++tot; //线段树中结点总个数
16     t[cur].Left=ll; 
17     t[cur].Right=rr;
18     if(ll!=rr-1)//非单位区间
19     {
20         t[cur].lptr=tot+1;
21         buildtree(ll,(ll+rr)/2);
22         t[cur].rptr=tot+1;
23         buildtree((ll+rr)/2,rr);
24         t[cur].sum=t[t[cur].lptr].sum+t[t[cur].rptr].sum;
25     }else t[cur].sum=a[ll];
26 }
27 void change(int k,int p,int delta) //修改单个元素的值,根节点作为第一个参数传入(k)
28 {
29     if(t[k].Left==t[k].Right-1) t[k].sum+=delta;
30     else
31     {
32         if (p<(t[k].Left+t[k].Right)/2)
33             change(t[k].lptr,p,delta);
34         if (p>=(t[k].Left+t[k].Right)/2)
35             change(t[k].rptr,p,delta);
36         t[k].sum=t[t[k].lptr].sum+t[t[k].rptr].sum;
37     }
38 }
39 int query(int k,int ll,int rr) //查询[ll,rr)区间和,根节点作为第一个参数传入(k)
40 {
41     if (ll<=t[k].Left&&rr>=t[k].Right) return t[k].sum;  //区间覆盖树
42     int ans=0;
43     if (ll<(t[k].Left+t[k].Right)/2) ans+=query(t[k].lptr,ll,rr);
44     if (rr>(t[k].Left+t[k].Right)/2) ans+=query(t[k].rptr,ll,rr);
45     return ans;
46 }
47 int main()
48 {
49     int n;
50     scanf("%d",&n);
51     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
52     buildtree(1,n+1);
53     cin>>n;
54     int p,at,x;
55     for (int i=1;i<=n;i++)
56     {
57         cin>>at>>x>>p;
58         if (at==1) change(1,x,p);
59         if (at==2) printf("%d
",query(1,x,p+1));
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/liumengyue/p/5097169.html