数据结构--M - 秋实大哥与线段树(单点更新与区间查询)

M - 秋实大哥与线段树

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

“学习本无底,前进莫徬徨。” 秋实大哥对一旁玩手机的学弟说道。

秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构。

为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作。

秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值;一种是询问一段区间的和。

Input

第一行包含一个整数n,表示序列的长度。

接下来一行包含n个整数ai,表示序列初始的元素。

接下来一行包含一个整数m,表示操作数。

接下来m行,每行是以下两种操作之一:

1 x v : 表示将第x个元素的值改为v 2 l r : 表示询问[l,r]这个区间的元素和

1nmvai1000001lrn

Output

对于每一个2 l r操作,输出一个整数占一行,表示对应的答案。

Sample input and output

Sample Input Sample Output
3

1 2 3

3

2 1 2

1 1 5

2 1 2
3

7

解题思路:

  这道题是一道裸裸的线段树的单点更新与区间查询[l,r]sum的问题.

直接套用线段树的模板就可以了,但是要注意long long ,,,因为a_i<=10^5,n<=10^5,且a_i*n<=10^10 > 2*10^9。

代码:

  1 # include<cstdio>

  2 # include<iostream>

  3 # include<fstream>

  4 # include<algorithm>

  5 # include<functional>

  6 # include<cstring>

  7 # include<string>

  8 # include<cstdlib>

  9 # include<iomanip>

 10 # include<numeric>

 11 # include<cctype>

 12 # include<cmath>

 13 # include<ctime>

 14 # include<queue>

 15 # include<stack>

 16 # include<list>

 17 # include<set>

 18 # include<map>

 19 

 20 using namespace std;

 21 

 22 const double PI=4.0*atan(1.0);

 23 

 24 typedef long long LL;

 25 typedef unsigned long long ULL;

 26 

 27 # define inf 999999999

 28 # define MAX 100004

 29 

 30 struct Segtree

 31 {

 32     int left, right;

 33     LL sum;

 34 }tree[MAX*4];

 35 

 36 int a[MAX];

 37 

 38 void build ( int id,int l,int r )

 39 {

 40     tree[id].left = l; tree[id].right = r;

 41     if ( l==r )

 42     {

 43         scanf("%lld",&tree[id].sum);

 44         return;

 45     }

 46     else

 47     {

 48         int mid = (l+r)>>1;

 49         build(id<<1,l,mid);

 50         build(id<<1|1,mid+1,r);

 51         tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum;

 52     }

 53 

 54 }

 55 

 56 void updata( int id,int pos,int val )

 57 {

 58     if ( tree[id].left==tree[id].right )

 59     {

 60         tree[id].sum = val;

 61     }

 62     else

 63     {

 64         int mid = ( tree[id].left+tree[id].right )>>1;

 65         if ( pos <= mid )

 66         {

 67             updata( id<<1,pos,val );

 68         }

 69         else

 70         {

 71             updata( id<<1|1,pos,val );

 72         }

 73         tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum;

 74     }

 75 }

 76 

 77 LL query( int id,int l,int r )

 78 {

 79     if ( tree[id].left==l&&tree[id].right==r )

 80     {

 81         return tree[id].sum;

 82     }

 83     else

 84     {

 85         int mid = ( tree[id].left+tree[id].right )>>1;

 86         if ( r <= mid )

 87         {

 88             query( id<<1,l,r );

 89         }

 90         else if ( l > mid )

 91         {

 92             query( id<<1|1,l,r );

 93         }

 94         else

 95         {

 96             return query( id<<1,l,mid)+query( id<<1|1,mid+1,r );

 97         }

 98     }

 99 }

100 

101 

102 int main(void)

103 {

104     int n;

105     while ( cin>>n )

106     {

107         memset(tree,0,sizeof(tree));

108         build(1,1,n);

109         int t;cin>>t;

110         while ( t-- )

111         {

112             int t1,a,b;

113             cin>>t1>>a>>b;

114             if ( t1==1 )

115             {

116                 updata(1,a,b);

117             }

118             else

119             {

120                 cout<<query(1,a,b)<<endl;

121             }

122         }

123     }

124 

125     return 0;

126 }

第二种写法:

区别就是对于原数组的处理,感觉第二种更能接受一点。

  1 # include<cstdio>

  2 # include<iostream>

  3 # include<fstream>

  4 # include<algorithm>

  5 # include<functional>

  6 # include<cstring>

  7 # include<string>

  8 # include<cstdlib>

  9 # include<iomanip>

 10 # include<numeric>

 11 # include<cctype>

 12 # include<cmath>

 13 # include<ctime>

 14 # include<queue>

 15 # include<stack>

 16 # include<list>

 17 # include<set>

 18 # include<map>

 19 

 20 using namespace std;

 21 

 22 const double PI=4.0*atan(1.0);

 23 

 24 typedef long long LL;

 25 typedef unsigned long long ULL;

 26 

 27 # define inf 999999999

 28 # define MAX 100004

 29 

 30 struct Segtree

 31 {

 32     int left, right;

 33     LL sum;

 34 }tree[MAX*4];

 35 

 36 LL a[MAX];

 37 

 38 void build ( int id,int l,int r )

 39 {

 40     tree[id].left = l; tree[id].right = r;

 41     if ( l==r )

 42     {

 43         tree[id].sum = a[l];

 44         return;

 45     }

 46     else

 47     {

 48         int mid = (l+r)>>1;

 49         build(id<<1,l,mid);

 50         build(id<<1|1,mid+1,r);

 51         tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum;

 52     }

 53 

 54 }

 55 

 56 void updata( int id,int pos,int val )

 57 {

 58     if ( tree[id].left==tree[id].right )

 59     {

 60         tree[id].sum = val;

 61     }

 62     else

 63     {

 64         int mid = ( tree[id].left+tree[id].right )>>1;

 65         if ( pos <= mid )

 66         {

 67             updata( id<<1,pos,val );

 68         }

 69         else

 70         {

 71             updata( id<<1|1,pos,val );

 72         }

 73         tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum;

 74     }

 75 }

 76 

 77 LL query( int id,int l,int r )

 78 {

 79     if ( tree[id].left==l&&tree[id].right==r )

 80     {

 81         return tree[id].sum;

 82     }

 83     else

 84     {

 85         int mid = ( tree[id].left+tree[id].right )>>1;

 86         if ( r <= mid )

 87         {

 88             query( id<<1,l,r );

 89         }

 90         else if ( l > mid )

 91         {

 92             query( id<<1|1,l,r );

 93         }

 94         else

 95         {

 96             return query( id<<1,l,mid)+query( id<<1|1,mid+1,r );

 97         }

 98     }

 99 }

100 

101 

102 int main(void)

103 {

104     int n;

105     while ( cin>>n )

106     {

107         for ( int i = 1;i <= n;i++ )

108         {

109             scanf("%lld",&a[i]);

110         }

111         memset(tree,0,sizeof(tree));

112         build(1,1,n);

113         int t;cin>>t;

114         while ( t-- )

115         {

116             int t1,a,b;

117             cin>>t1>>a>>b;

118             if ( t1==1 )

119             {

120                 updata(1,a,b);

121             }

122             else

123             {

124                 cout<<query(1,a,b)<<endl;

125             }

126         }

127     }

128 

129     return 0;

130 }

 

你可能感兴趣的:(数据结构)