线段树的两道模板题 hdu1698 hdu1166

最近学到了线段树,觉得挺不错的一个数据结构,这里有两个标准的模板题,代码也是别人哪里看到的,自愧不如;

hdu1166: 



#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define MAXN 50005
typedef long long LL;

LL arr[MAXN], sum = 0;
struct node {
	LL l, r;//储存当前记录的区间[l, r] 
	LL persons;
}Tree[MAXN*4];

void maintain(LL root) {
	LL L=root<<1, R=root<<1|1;
	Tree[root].persons = Tree[L].persons + Tree[R].persons;
}

void Build(LL root, LL start, LL end) {
	Tree[root].l = start;
	Tree[root].r = end;
	if(start == end) {
		Tree[root].persons = arr[start];
		return;
	}	
	LL mid = (Tree[root].l+Tree[root].r)>>1;
	Build(root<<1, start, mid);
	Build(root<<1|1, mid+1, end);
	maintain(root);
}

void Add(LL root, LL pos, LL value) {
	if(Tree[root].l == Tree[root].r) {
		Tree[root].persons += value;
		return;
	}
	LL mid = (Tree[root].l+Tree[root].r)>>1;
	if(pos <= mid)
		Add(root<<1, pos, value);
	else
		Add(root<<1|1, pos, value);
	maintain(root);
}

void Sub(LL root, LL pos, LL value) {
	if(Tree[root].l == Tree[root].r) {
		Tree[root].persons -= value;
		return;
	}
	LL mid = (Tree[root].l+Tree[root].r)>>1;
	if(pos <= mid)
		Sub(root<<1, pos, value);
	else
		Sub(root<<1|1, pos, value);
	maintain(root);
}

void Query(LL root, LL start, LL end) {
	if(start > Tree[root].r || Tree[root].l > end) return;
	if(start <= Tree[root].l && Tree[root].r <= end) {
		sum += Tree[root].persons;
		return;
	} 
	Query(root<<1, start, end);
	Query(root<<1|1, start, end);
}

int main() {
	int T, N, kase = 1;
	scanf("%d",&T);
	while(T--) {
		scanf("%d",&N);
		for(int i=1; i <= N; i++)
			scanf("%lld",&arr[i]);
		Build(1, 1, N);
//		getchar();
		printf("Case %d:\n",kase++);
		char msg[10];
		while(~scanf("%s",msg) && strcmp(msg,"End")) {
			LL X, Y;
			scanf("%lld%lld",&X, &Y);
			if(!strcmp(msg,"Query")) {
//				printf("%s %d %d\n",msg, X, Y);
				sum = 0;
				Query(1, X, Y);
				printf("%lld\n",sum);
			}
			else if(!strcmp(msg,"Add")) Add(1, X, Y);
			else if(!strcmp(msg,"Sub")) Sub(1, X, Y);
		}
	}
	return 0;
}


hdu1698:




#include <cstdio>
#include <iostream>
using namespace std;
#define MAXN 100005
#define INF 99999999

typedef long long LL;

struct node {
	LL l, r, sum, lazy, v;
}tree[MAXN<<2];

void maintain(LL root) {
	LL L=root<<1, R=root<<1|1;
	tree[root].sum = tree[L].sum + tree[R].sum;
}

void Build(LL root, LL start, LL end) {
	tree[root].l = start;
	tree[root].r = end;
	tree[root].lazy = 0;
	tree[root].v = 0;
	if(start == end) {
		tree[root].sum = 1;
		return ;
	}
	LL mid = (start+end)>>1;
	Build(root<<1, start, mid);
	Build(root<<1|1, mid+1, end);
	maintain(root); 
}

void update(LL root, LL X, LL Y, LL Z) {
	if(tree[root].l == X && tree[root].r == Y) {
		tree[root].v = Z;
		tree[root].lazy = 1;
		tree[root].sum = (Y-X+1)*Z;
		return ;
	}
	LL mid = (tree[root].l+tree[root].r)>>1;
	if(tree[root].lazy == 1) {
		tree[root].lazy = 0;
		update(root<<1, tree[root].l, mid, tree[root].v);
		update(root<<1|1, mid+1, tree[root].r, tree[root].v);
		tree[root].v = 0;
	}
	if(mid >= Y) {
		update(root<<1, X, Y, Z);
	}else if(mid < X) {
		update(root<<1|1, X, Y, Z);		
	}else {
		update(root<<1, X, mid, Z);		
		update(root<<1|1, mid+1, Y, Z);		
	}
	maintain(root);
}

int main()  {
	int T, kase=1, N, Q;
	scanf("%d",&T);
	while(T--) {
		scanf("%d%d",&N, &Q);
		Build(1, 1, N);
		while(Q--) {
			LL X, Y, Z;
			scanf("%lld%lld%lld",&X,&Y,&Z);
			update(1, X, Y, Z);
		}
		printf("Case %d: The total value of the hook is %lld.\n",kase++, tree[1].sum);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值