您的位置:首页 > 其它

线段树的应用(最大值,区间求和)

2012-04-29 20:15 288 查看
//线段树中不是懒方法建立,修改(某个数据),查询区间和(sum)与最大值(max)
#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=1000;
struct
{
int left,right;     //区间的端点
int max,sum;  //视题目要求而定
} tree[MAXN*4] ;
int a[MAXN]={0,1,2,3,4,5,6,7,8,9,10} ;//仅用于实验

int max(int a,int b)
{
return a>b?a:b;
}
void build(int id,int l,int r)
{
tree[id].left=l; tree[id].right=r;
if (l==r)//已到达叶子
{
tree[id].sum=tree[id].max=a[l];//在根结点上,sum,max 的结果相等,都为a[l]本身

//tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
// tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
return;
}
else
{
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
}
}

void update(int id,int pos,int val)//此外为将第pos个数改为val
{
if (tree[id].left==tree[id].right)
{
tree[id].sum=tree[id].max=val;
}
else
{
int mid=(tree[id].left+tree[id].right)/2;
if (pos<=mid) update(id*2,pos,val);//更新左子树
else update(id*2+1,pos,val);//更新右子树
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
}
}
int query(int id,int l,int r)  //这是查询总和的函数
{
if (tree[id].left==l&&tree[id].right==r)
return tree[id].sum; //询问总和
else
{
int mid=(tree[id].left+tree[id].right)/2;
if (r<=mid) return query(id*2,l,r);
else if (l>mid)
return query(id*2+1,l,r);
else
return query(id*2,l,mid)+query(id*2+1,mid+1,r);
}
}
int query_max(int id,int l,int r)
{
if(tree[id].left==l&&tree[id].right==r)
{
return tree[id].max;
}
else
{
int mid=(tree[id].left+tree[id].right)/2;
if(r<=mid) return query_max(id*2,l,r);
else if(l>mid) return query_max(id*2+1,l,r);
else return query_max(id*2,l,mid)+query_max(id*2+1,mid+1,r);
}
}

int main()
{

int n=10;

build(1,1,n);
// printf("%d\n",query(1,1,10));

cout<<query_max(1,1,10)<<endl;

update(1,3,15);
cout<<query_max(1,1,10)<<endl;

}


本文出自 “与谁争峰” 博客,请务必保留此出处http://wwwacm.blog.51cto.com/3014849/847405
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: