nyoj108 士兵杀敌(一) 线段树

本题利用线段树求区间和。
用build(int k,int l,int r)构建二叉线段树。k代表节点序号,l,r分别是区间左右。
递归构建左右子树(随即更新节点的区间和),递归结束的条件为节点区间的左右相等时即为叶节点。
用search(int k,int l,int r)查找区间和。k代表该节点。l,r是要查询区间和的左右端,当要查找的区间的左端大于该节点的中点时,递归查找该节点的右子树,当要查找的区间的右端小于等于中点时,递归查找该节点的左子树。当左端小于等于中点且右端大于中点时,则把递归查找左子树和右子树并把两者的区间和加起来。递归结束的条件为当前k节点的区间左右分别和要查找的区间相等。
 

#include <bits/stdc++.h>
#define maxn 1000000*4+50
using namespace std;
struct node{
	int l,r,sum;
}t[maxn];
void build(int k,int l,int r){
	t[k].l=l;t[k].r=r;
	if(t[k].l==t[k].r){
		scanf("%d",&t[k].sum);//cin>>t[k].sum;
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
}
int search(int k,int l,int r){
	if(t[k].l==l&&t[k].r==r)
	return t[k].sum;
	int mid=(t[k].l+t[k].r)>>1;
	if(mid>=r)
	search(k<<1,l,r);
	else if(mid<l)
	search(k<<1|1,l,r);
	else
	return search(k<<1,l,mid)+search(k<<1|1,mid+1,r);
}
int main(){
	int n,m,l,r;
	scanf("%d %d",&n,&m);//cin>>n>>m;
	build(1,1,n);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&l,&r);//cin>>l>>r;
		printf("%d\n",search(1,l,r));//cout<<search(1,l,r)<<endl;
	}
}
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值