线段树的两道模板题 hdu1698 hdu1166

来源:互联网 发布:网络鬼故事之603房间 编辑:程序博客网 时间:2024/05/19 16:22

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

hdu1166: 



#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define MAXN 50005typedef 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);elseAdd(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);elseSub(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 99999999typedef 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;}