线段树用来解决符合结合律的区间求极值,区间求和,求区间最大公约数等类似问题
线段树作为一种工具,可以将区间修改维护的时间从O(N)降到O(logN)
1.线段树求区间和的简单入门
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define ls(k) (k)<<1
#define rs(k) (k)<<1|1
/**
定义线段树结构
sum
l
r
lazytag
**/
struct node{
int l; //区间左端点
int r; //区间右端点
int sum; //区间和
int lazy;//懒标记
}tree[MAXN*4];
int a[MAXN];
//开始建树
void buildTree(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
//到达叶子节点
if(tree[i].l==tree[i].r){
tree[i].sum=a[l];
return;
}
int mid=(l+r)>>1;
buildTree(ls(i),l,mid);
buildTree(rs(i),mid+1,r);
tree[i].sum=tree[ls(i)].sum+tree[rs(i)].sum;
}
//查询区间和
int query(int i,int l,int r){
if(tree[i].l==l&&tree[i].r==r){
return tree[i].sum;
}
//往左边找
if(tree[ls(i)].r>=r){
return query(ls(i),l,r);
}
//往右边找
else if(tree[rs(i)].l<=l){
return query(rs(i),l,r);
}
else{
//有交集
return query(ls(i),l,tree[ls(i)].r)+query(rs(i),tree[rs(i)].l,r);
}
}
int main(){
int n=10;
for(int i=1;i<=n;i++){
a[i]=i;
}
buildTree(1,1,10);
int res=query(1,1,10);
printf("%d",res);
return 0;
}
有话要说...