1. 程式人生 > >線段樹的建立,單個節點的修改,求區間和問題(求區間的和)

線段樹的建立,單個節點的修改,求區間和問題(求區間的和)

 程式碼如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
struct tree
{
    int l,r;
    int sum;
}; //線段樹的基本結構
tree t[800005];
int a[200005];
int sum=0;
void create (int loc,int l,int r) //建立一個線段樹
{
    t[loc].l=l;
    t[loc].r=r;
    if(l==r)
    {
        t[loc].sum=a[l];
        //printf("%d %d\n",l,t[loc].sum);
        t[loc].l=l;
        t[loc].r=r;
        return ;
    }
    int mid=(l+r)/2;
    create (2*loc,l,mid);
    create (2*loc+1,mid+1,r);
    t[loc].sum+=t[2*loc].sum+t[2*loc+1].sum;
}
void  mod(int loc,int aloc,int zhi) //修改線段樹節點的值
{
    if(t[loc].l==t[loc].r)
    {
        //printf("%d\n",t[loc].l);
        t[loc].sum=zhi;
        return ;
    }
    int mid=(t[loc].l+t[loc].r)/2;
    if(mid<aloc)
         mod (2*loc+1,aloc,zhi);
    else
         mod (2*loc,aloc,zhi);
}
void qujiansum (int left,int right,int loc) //求線段樹區間的值
{
    if(t[loc].l>=left&&t[loc].r<=right)
    {
        sum+=t[loc].sum;
        return;
    }
    int mid=(t[loc].l+t[loc].r)/2;
    if(right>mid)
        qujiansum(left,right,2*loc+1);
    if(mid>=left)
        qujiansum(left,right,2*loc);
}
int main()
{
   int n;
   while (scanf("%d",&n)!=EOF&&n)
   {
       sum=0;
       for (int i=1;i<=n;i++)
       {
           scanf("%d",&a[i]);
       }
       create (1,1,n);
       mod (1,2,0);
       qujiansum(2,4,1);
       printf("%d\n",sum);
   }
    return 0;
}