您的位置:首页 > 其它

线段树的两道模板题 hdu1698 hdu1166

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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: