您的位置:首页 > 其它

线段树练习(1)

2016-08-03 15:22 239 查看
现在我们来做几个最基础的线段树区间查询,单点更新,以及区间求和的模板题
1、hdu1166 敌兵布阵
分析: update:单点增减   query:区间求和

#include <cstdio>
#include <iostream>

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1 | 1

using namespace std;
const int maxn = 50050;
int sum[maxn<<2];
int n;

void pushup(int rt) //向上更新
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &sum[rt]);
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}

void update(int p, int add, int l, int r, int rt)
{
if(l == r)
{
sum[rt] += add;
return ;
}
int m = (l+r) >> 1;
if(p <= m)
update(p, add, lson);
else update(p, add, rson);
pushup(rt);
}

int query(int L, int R, int l, int r, int rt)
{
if(L<=l && r<=R) return sum[rt];
int m = (l+r)>>1;
int ret = 0;
if(L <= m) ret += query(L, R, lson); //与前一个博客所画图类似
if(m < R) ret += query(L, R, rson);
return ret;
}

int main()
{
int t;
scanf("%d", &t);
char str[22];
for(int i=1; i<=t; i++)
{
scanf("%d", &n);
build(1, n, 1);
printf("Case %d:\n", i);
while(scanf("%s", str))
{
if(str[0] == 'E') break;
int a, b;
scanf("%d%d", &a, &b);
if(str[0] == 'A')
{
update(a, b, 1, n, 1);
}
else if(str[0] == 'S')
{
update(a, -b, 1, n, 1); // 正负号的处理是一个精髓
}
else if(str[0] == 'Q')
{
printf("%d\n", query(a, b, 1, n, 1) );
}
}
}
return 0;
}
2、hdu 1754 I Hate It
update:单点更新 query:区间最值
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
using namespace std;

int segtree[800005];
void build(int left,int right,int node)
{
if(left == right)
{
scanf("%d",&segtree[node]);
}
else
{
int m=(left+right)>>1;
build(left,m,node<<1);
build(m+1,right,node<<1|1);
segtree[node]=max(segtree[node<<1],segtree[node<<1|1]);
}
}

void update(int p,int change,int left,int right,int node)
{
if(left==right)
{
segtree[node]=change;
}
else
{
int m=(left+right)>>1;
if(p<=m)update(p,change,left,m,node<<1);
else update(p,change,m+1,right,node<<1|1);
segtree[node]=max(segtree[node<<1],segtree[node<<1|1]);
}
}

int query(int x,int y,int left,int right,int node)
{
if(x<=left&&right<=y)
{
return segtree[node];
}
else
{
int sum=0,m=(left+right)>>1;
if(x<=m)sum=max(sum,query(x,y,left,m,node<<1));
if(y>m)sum=max(sum,query(x,y,m+1,right,node<<1|1));
return sum;
}
}

int main()
{

int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
while(m--)
{
char o[3];
int x,y;
scanf("%s%d%d",o,&x,&y);
if(o[0]=='U')
update(x,y,1,n,1);
else
printf("%d\n",query(x,y,1,n,1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: