zoukankan      html  css  js  c++  java
  • 数据结构--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 InputSample 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 }
  • 相关阅读:
    【初心】
    【杂题集】单题小总结
    【模板】(旧)矩阵模板
    【机智题?】【Vijos】【天平称量】
    【杂题集】【51NOD 1267】4个数和为0
    【模板】(旧)Miller Rabin 素数判定
    【杂谈】只是想想
    【杂谈】思考
    【学习?】组合和排序
    【模版】读入优化
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4436470.html
Copyright © 2011-2022 走看看