线段树的两道模板题 hdu1698 hdu1166
2017-11-21 18:24
281 查看
最近学到了线段树,觉得挺不错的一个数据结构,这里有两个标准的模板题,代码也是别人哪里看到的,自愧不如;
hdu1166:
hdu1698:
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; }
相关文章推荐
- hdu1166 敌兵布阵(线段树点更新模板题)
- Hdu1166-- 线段树模板
- 【线段树成段更新-模板】【HDU1698】Just a Hook
- hdu1698(线段树区间替换模板)
- 【线段树成段更新-模板】【HDU1698】Just a Hook
- 线段树区间更新(2)(lazy)(区间都变为v)(序号从1开始)(O(logn))模板(hdu1698)
- [hdu1166]线段树模板
- 线段树模板 hdu1166
- hdu1166线段树的点跟新模板
- hdu1166 敌兵布阵+线段树模板题+单点修改
- hdu1166(线段树单点更新&区间求和模板)
- hdu1698(线段树区间更新模板)
- hdu1166(线段树模板)
- 线段树基本操作模板 hdu1166 hdu1754
- hdu1166(线段树模板题)
- HDU1698:Just a Hook(线段树区域更新模板题)
- 线段树模板(区间修改)——hdu1698
- hdu1166 敌兵布阵 (线段树模板)
- 线段树经典操作模板(单点更新,替换;区间更新,替换;区间求和求最值)
- 模板,线段树,矩形轮廓周长