这是一篇被放弃的博客。。不要看了。。(新手千万不要手撸模板)

今天解除了一下线段树 据自己理解手撸了发建树与查询的操作 的模板

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <vector>
#include <time.h>

using namespace std;

#define  LL  long long int 

int a[1010101];

struct node
{
    int value ;
    int right , left;

}tree[4040404];


int firstbuild(int o,int l,int r)//从第O个节点 开始建树  不断递归 知道最后到叶子节点
{
    tree[o].left  = l;
    tree[o].right = r;
    tree[o].value = 0;

    if(l==r)
    {
        tree[o].value = a[l];
        return tree[o].value ;
    }
    int mid = (l+r) >> 1;

    tree[o].value=firstbuild(o * 2,l,mid)+firstbuild(o*2+1,mid+1,r);
    return tree[o].value;
}

int query(int o,int &l,int &r)
{
    //printf("%d--->%d %d\n",o,tree[o].left,tree[o].right); 

    int sum=0;
    //首先判断是不是属于所要查询的区间   
    if(l<=tree[o].left&&tree[o].right<=r)      //如果该区间属于要查询的区间内  就加上  而且不向下递归了  最终的加和一定是这些区间的和 而且不会重复 不会
        sum += tree[o].value;
    else if(tree[o].right<l||r<tree[o].left) ;
    //如果区间有重合部分但又不包含 就要继续递归子节点 寻找区间。。 
    else if(tree[o].left<l||r<tree[o].right)  //区间过大了  就递归缩小区间
        sum += query(o*2,l,r) + query(o*2+1,l,r);
    else  ; //区间完全不重合 就没有在向下查询的必要了 

    return sum;
}

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }


    firstbuild(1,1,n);
    for(int i=1;i<=n*2-1;i++)
        printf("%d %d\n",tree[i].left,tree[i].right); 
    puts("");
    int nu=0,un=1;
    for(int i=1;i<=n*2-1;i++)
    {
        if(nu>=un)
        {
            nu=0,un*=2;
            puts("");
        }
        nu++;
        printf("%d ",tree[i].value);
    }
    puts("");
    while(true)
    {
        int l,r;
        cin>>l>>r;
        if(l==0||r==0) break;
        printf("%d\n",query(1,l,r));
    }
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值