线段树模板
2016-08-13 10:23
253 查看
int date[MAXN];//存放输入数据
struct Node
{
int left,right;
int sum;
}tree[MAXN*4];//定义数的结点
//建树
void Build(int k,int l,int r)
{
tree[k].left=l;
tree[k].right=r;
if(tree[k].left==tree[k].right)
{
tree[k].sum=date[tree[k].left];
return;
}
else
{
int mid=(l+r)/2;
Build(k<<1,l,mid);
Build((k<<1)+1,mid+1,r);
tree[k].sum=tree[k<<1].sum+tree[(k<<1)+1].sum;
}
}
//查询功能
int query(int k,int l,int r)//k一般为1, 查询l到r的和
{
if(tree[k].left==l&&tree[k].right==r)
return tree[k].sum;
else
{
int mid =(tree[k].left+tree[k].right)/2;
if(l>mid)//完全在右子树
return query((k<<1)+1,l,r);
else if(r<=mid)//完全在左子树
return query(k<<1,l,r);
else//左右子树都有
return query(k<<1,l,mid)+query((k<<1)+1,mid+1,r);
}
}
//单点更新
void Update(int k,int l,int r,int pos,int delta)//k一般为1,更新在l到r的范围内 date【pos】 处加上delta(变量,增量)
{
if(tree[k].left>pos||tree[k].right<pos)//如果pos不在当前tree【k】的范围内 就直接返回
return ;
if(tree[k].left==tree[k].right)//相当于==pos
{
tree[k].sum+=delta;
return ;
}
int mid=(tree[k].left+tree[k].right)/2;
if(l>mid) // l > mid说明pos一定落在右子树范围内
Update((k<<1)+1,l,r,pos,delta);
else if(r<=mid)/// r <= mid说明pos一定落在左子树范围内
Update(k<<1,l,r,pos,delta);
else// 若l,r在mid两端,则将区间[l,r]分成[l,mid]和[mid+1,r]递归查找
{
Update(k<<1,l,mid,pos,delta);
Update((k<<1)+1,mid+1,r,pos,delta);
}
tree[k].sum=tree[k<<1].sum+tree[(k<<1)+1].sum;
}
struct Node
{
int left,right;
int sum;
}tree[MAXN*4];//定义数的结点
//建树
void Build(int k,int l,int r)
{
tree[k].left=l;
tree[k].right=r;
if(tree[k].left==tree[k].right)
{
tree[k].sum=date[tree[k].left];
return;
}
else
{
int mid=(l+r)/2;
Build(k<<1,l,mid);
Build((k<<1)+1,mid+1,r);
tree[k].sum=tree[k<<1].sum+tree[(k<<1)+1].sum;
}
}
//查询功能
int query(int k,int l,int r)//k一般为1, 查询l到r的和
{
if(tree[k].left==l&&tree[k].right==r)
return tree[k].sum;
else
{
int mid =(tree[k].left+tree[k].right)/2;
if(l>mid)//完全在右子树
return query((k<<1)+1,l,r);
else if(r<=mid)//完全在左子树
return query(k<<1,l,r);
else//左右子树都有
return query(k<<1,l,mid)+query((k<<1)+1,mid+1,r);
}
}
//单点更新
void Update(int k,int l,int r,int pos,int delta)//k一般为1,更新在l到r的范围内 date【pos】 处加上delta(变量,增量)
{
if(tree[k].left>pos||tree[k].right<pos)//如果pos不在当前tree【k】的范围内 就直接返回
return ;
if(tree[k].left==tree[k].right)//相当于==pos
{
tree[k].sum+=delta;
return ;
}
int mid=(tree[k].left+tree[k].right)/2;
if(l>mid) // l > mid说明pos一定落在右子树范围内
Update((k<<1)+1,l,r,pos,delta);
else if(r<=mid)/// r <= mid说明pos一定落在左子树范围内
Update(k<<1,l,r,pos,delta);
else// 若l,r在mid两端,则将区间[l,r]分成[l,mid]和[mid+1,r]递归查找
{
Update(k<<1,l,mid,pos,delta);
Update((k<<1)+1,mid+1,r,pos,delta);
}
tree[k].sum=tree[k<<1].sum+tree[(k<<1)+1].sum;
}
相关文章推荐
- luogu P3373 【模板】线段树 2
- 【线段树区间最值单点更新模板】BNUOJ 52965 E Excellent Engineers
- 【洛谷P3372】【模板】线段树 1
- 【线段树成段更新-模板】【HDU1698】Just a Hook
- 线段树最基本的模板
- 线段树模板(lazy标记)ZOJ 3686
- hdu1166敌兵布阵(线段树模板)
- HDU 1754 B I Hate It 线段树 单点更新 区间最大值 模板
- 树状数组 线段树 模板
- 有关线段树的基本操作模板
- 线段树 单点增减,单点替换,区间最值,区间求和(模板)
- 模板 权值线段树
- hdu_1166_线段树模板
- 线段树模板
- 分块【线段树模板】
- hdu1754 I hate it线段树模板 区间最值查询
- POJ 1151 & HDU 1542 Atlantis(扫描线模板 线段树 离散化)
- 线段树模板
- poj 1195 二维线段树(模板题)
- 线段树模板