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

2016-08-05 13:33:21 Tabris_ 阅读数:1044


博客爬取于2020-06-14 22:43:58
以下为正文

版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52128243


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

tree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 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;
}