线段树的应用(最大值,区间求和)

 

  
  
           
  
  
  1. //线段树中不是懒方法创建,修改(某个数据),查询区间和(sum)与最大值(max)  
  2. #include<cstdio>  
  3. #include<iostream>  
  4. using namespace std;  
  5. const int MAXN=1000;  
  6. struct 
  7. {  
  8.    int left,right;     //区间的端点  
  9.    int max,sum;  //视题目要求而定  
  10. } tree[MAXN*4] ;  
  11. int a[MAXN]={0,1,2,3,4,5,6,7,8,9,10} ;//仅用于实验  
  12.  
  13. int max(int a,int b)  
  14. {  
  15.     return a>b?a:b;  
  16. }  
  17. void build(int id,int l,int r)  
  18. {  
  19.     tree[id].left=l; tree[id].right=r;  
  20.     if (l==r)//已到达叶子  
  21.     {  
  22.         tree[id].sum=tree[id].max=a[l];//在根结点上,sum,max 的结果相等,都为a[l]自己  
  23.  
  24.         //tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;  
  25.        // tree[id].max=max(tree[id*2].max,tree[id*2+1].max);  
  26.         return;  
  27.     }  
  28.     else 
  29.     {  
  30.         int mid=(l+r)/2;  
  31.         build(id*2,l,mid);  
  32.         build(id*2+1,mid+1,r);  
  33.         tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;  
  34.         tree[id].max=max(tree[id*2].max,tree[id*2+1].max);  
  35.     }  
  36. }  
  37.  
  38. void update(int id,int pos,int val)//此外为将第pos个数改成val  
  39. {  
  40.     if (tree[id].left==tree[id].right)  
  41.     {  
  42.         tree[id].sum=tree[id].max=val;  
  43.     }  
  44.     else 
  45.     {  
  46.         int mid=(tree[id].left+tree[id].right)/2;  
  47.         if (pos<=mid) update(id*2,pos,val);//更新左子树  
  48.         else update(id*2+1,pos,val);//更新右子树  
  49.         tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;  
  50.         tree[id].max=max(tree[id*2].max,tree[id*2+1].max);  
  51.     }  
  52. }  
  53. int query(int id,int l,int r)  //这是查询总和的函数  
  54. {  
  55.     if (tree[id].left==l&&tree[id].right==r)  
  56.         return tree[id].sum; //询问总和  
  57.     else 
  58.     {  
  59.         int mid=(tree[id].left+tree[id].right)/2;  
  60.         if (r<=mid) return query(id*2,l,r);  
  61.         else if (l>mid)  
  62.             return query(id*2+1,l,r);  
  63.         else 
  64.             return query(id*2,l,mid)+query(id*2+1,mid+1,r);  
  65.     }  
  66. }  
  67. int query_max(int id,int l,int r)  
  68. {  
  69.     if(tree[id].left==l&&tree[id].right==r)  
  70.     {  
  71.         return tree[id].max;  
  72.     }  
  73.     else 
  74.     {  
  75.         int mid=(tree[id].left+tree[id].right)/2;  
  76.         if(r<=mid) return query_max(id*2,l,r);  
  77.         else if(l>mid) return query_max(id*2+1,l,r);  
  78.         else return query_max(id*2,l,mid)+query_max(id*2+1,mid+1,r);  
  79.     }  
  80. }  
  81.  
  82.  
  83. int main()  
  84. {  
  85.  
  86.         int n=10;  
  87.  
  88.         build(1,1,n);  
  89.        // printf("%d\n",query(1,1,10));  
  90.  
  91.  
  92.         cout<<query_max(1,1,10)<<endl;  
  93.  
  94.         update(1,3,15);  
  95.         cout<<query_max(1,1,10)<<endl;  
  96.  
  97.  
  98.  
  99.  
  100.  
  101. }