HDU 1166 敌兵布阵 (线段树 单点更新)
2014-08-04 17:23
375 查看
题目链接
线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯。。就从这个题开始吧!
注释的代码:
线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯。。就从这个题开始吧!
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cstdlib> #include <algorithm> const int maxn = 50000+10; using namespace std; int a[maxn], n; struct line { int l, r, val; }tr[maxn<<2]; void build(int o, int l, int r) { tr[o].l = l; tr[o].r = r; if(l == r) { tr[o].val = a[l]; return; } int mid = (l+r)>>1; build(2*o, l, mid); build(2*o+1, mid+1, r); tr[o].val = tr[2*o].val+tr[2*o+1].val; } int query(int o, int l, int r) { if(tr[o].l==l && tr[o].r==r) return tr[o].val; int mid = (tr[o].l+tr[o].r)>>1; if(r <= mid) query(2*o, l, r); else if(l > mid) query(2*o+1, l, r); else return (query(2*o, l, mid)+query(2*o+1, mid+1, r)); } void update(int o, int p, int add) { if(tr[o].l==tr[o].r&&tr[o].l==p) { tr[o].val += add; return; } int mid = (tr[o].l+tr[o].r)>>1; if(p<=mid) update(2*o, p, add); else update(2*o+1, p, add); tr[o].val = tr[2*o].val+tr[2*o+1].val; } int main() { int t, i, ca = 1; int p, add, l, r; char s[20]; scanf("%d", &t); while(t--) { scanf("%d", &n); for(i = 1; i <= n; i++) scanf("%d", &a[i]); printf("Case %d:\n", ca++); build(1, 1, n); while(~scanf("%s", s)) { if(strcmp(s, "End")==0) break; if(s[0]=='Q') { scanf("%d%d", &l, &r); printf("%d\n", query(1, l, r)); } if(s[0]=='A') { scanf("%d%d", &p, &add); update(1, p, add); } if(s[0]=='S') { scanf("%d%d", &p, &add); update(1, p, -add); } } } return 0; }
注释的代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cstdlib> #include <algorithm> const int maxn = 50000+10; using namespace std; int a[maxn], n; struct line { int l, r, val; //val表示该区间的和 }tr[maxn<<2]; void build(int o, int l, int r) //o代表当前节点编号 { tr[o].l = l; tr[o].r = r; if(l == r) { tr[o].val = a[l]; return; } int mid = (l+r)>>1; build(2*o, l, mid); build(2*o+1, mid+1, r); tr[o].val = tr[2*o].val+tr[2*o+1].val; //建树把值从下往上加起来 } int query(int o, int l, int r) //求l到r的和 { if(tr[o].l==l && tr[o].r==r) //节点的区间吻合返回 return tr[o].val; int mid = (tr[o].l+tr[o].r)>>1; if(r <= mid) query(2*o, l, r); else if(l > mid) query(2*o+1, l, r); else return (query(2*o, l, mid)+query(2*o+1, mid+1, r)); //横跨了区间 } void update(int o, int p, int add) //对p节点增加add { if(tr[o].l==tr[o].r&&tr[o].l==p) { tr[o].val += add; return; } int mid = (tr[o].l+tr[o].r)>>1; if(p<=mid) update(2*o, p, add); else update(2*o+1, p, add); tr[o].val = tr[2*o].val+tr[2*o+1].val; //找到值以后的更新 } int main() { int t, i, ca = 1; int p, add, l, r; char s[20]; scanf("%d", &t); while(t--) { scanf("%d", &n); for(i = 1; i <= n; i++) scanf("%d", &a[i]); printf("Case %d:\n", ca++); build(1, 1, n); while(~scanf("%s", s)) { if(strcmp(s, "End")==0) break; if(s[0]=='Q') { scanf("%d%d", &l, &r); printf("%d\n", query(1, l, r)); } if(s[0]=='A') { scanf("%d%d", &p, &add); update(1, p, add); } if(s[0]=='S') { scanf("%d%d", &p, &add); update(1, p, -add); } } } return 0; }
相关文章推荐
- HDU 1166 敌兵布阵(线段树,单点更新 || 树状数组)
- hdu 1166 敌兵布阵(线段树-单点更新,区间求和)
- 敌兵布阵 - HDU 1166 单点更新线段树
- HDU 1166 敌兵布阵(线段树 单点更新)
- hdu 1166 敌兵布阵 线段树 单点更新
- 线段树 hdu 1166 敌兵布阵 单点更新区间求和
- [ACM] hdu 1166 敌兵布阵 (线段树,单点更新)
- hdu 1166 敌兵布阵 线段树(单点更新)
- hdu 1166 敌兵布阵(线段树,单点更新)
- HDU 1166 敌兵布阵 //线段树单点更新
- Hdu-1166 敌兵布阵【线段树(单点更新)】
- HDU 1166-敌兵布阵(线段树:单点更新,区间求和)
- hdu 1166 敌兵布阵(线段树-单点更新)
- hdu 1166 敌兵布阵(线段树之 单点更新+区间求和)
- HDU 1166 敌兵布阵 [线段树-单点更新]
- 线段树 hdu 1166 敌兵布阵 单点更新区间求和
- HDU 1166-敌兵布阵(线段树_单点更新)
- [ACM] hdu 1166 敌兵布阵 (线段树,单点更新)
- hdu 1166 敌兵布阵(线段树——单点更新)
- hdu 1166 敌兵布阵 线段树单点更新