2017暑假训练之线段树
2017-08-23 20:02
232 查看
线段树优点在于可以用数组来实现树形结构,大大简化代码。
单点更新,区间查询
HDUOJ 1166 敌兵布阵 374ms
HDUOJ 1754 I Hate It 1045ms
HDUOJ 1754 I Hate It 1145ms
POJ 3468 A Simple Problem with Integers 1641ms
单点更新,区间查询
HDUOJ 1166 敌兵布阵 374ms
#define lson cur<<1, l, mid #define rson cur<<1 | 1, mid+1, r int n, a[maxn], sum[maxn << 2]; void pushup(int cur) { sum[cur] = sum[cur << 1] + sum[cur << 1 | 1]; } void build(int cur, int l, int r) { if (l == r) sum[cur] = a[l]; else { int mid = Mid(l, r); build(lson); build(rson); pushup(cur); } } void update(int i, int val, int cur, int l, int r) { if (l == r) sum[cur] += val; else { int mid = Mid(l, r); if (i <= mid) update(i, val, lson); else update(i, val, rson); pushup(cur); } //pushup(cur);pushup过程不应在更新值后进行,此时cur并无lson与rson } int query(int L, int R, int cur, int l, int r) { if (L <= l && r <= R) return sum[cur]; int mid = Mid(l, r), ret = 0; if (L <= mid) ret += query(L, R, lson); if (R > mid) ret += query(L, R, rson); return ret; } int main() { int T, kase = 1; SF(T); while (T--) { int n; SF(n); FOR(i, 1, n + 1) SF(a[i]); build(1, 1, n); char op[6]; int l, r; printf("Case %d:\n", kase++); while (scanf("%s", op) && strcmp(op, "End")) { SFF(l, r); if (op[0] == 'Q') PF(query(l, r, 1, 1, n)); else if (op[0] == 'S') update(l, -r, 1, 1, n); else update(l, r, 1, 1, n); } } return 0; }线段树求区间最值
HDUOJ 1754 I Hate It 1045ms
#define lson cur<<1, l, mid #define rson cur<<1 | 1, mid+1, r int n, a[maxn], sum[maxn << 2]; void pushup(int cur) { sum[cur] = max(sum[cur << 1], sum[cur << 1 | 1]); } void build(int cur, int l, int r) { if (l == r) sum[cur] = a[l]; else { int mid = Mid(l, r); build(lson); build(rson); pushup(cur); } } void update(int i, int val, int cur, int l, int r) { if (l == r) sum[cur] = val; else { int mid = Mid(l, r); if (i <= mid) update(i, val, lson); else update(i, val, rson); pushup(cur); } } int query(int L, int R, int cur, int l, int r) { if (L <= l && r <= R) return sum[cur]; int mid = Mid(l, r), ret = 0; if (L <= mid) ret = max(query(L, R, lson), ret); if (R > mid) ret = max(query(L, R, rson), ret); return ret; } int main() { int q; while (~SFF(n, q)) { FOR(i, 1, n + 1) SF(a[i]); build(1, 1, n); char op[2]; int l, r; while (q--) { scanf("%s%d%d", op, &l, &r); if (op[0] == 'Q') PF(query(l, r, 1, 1, n)); else update(l, r, 1, 1, n); } } return 0; }非递归(雾)写法
HDUOJ 1754 I Hate It 1145ms
#define lson cur<<1, l, mid #define rson cur<<1 | 1, mid+1, r int _n, n, a[maxn], sum[maxn << 2]; void build() { n = 1; while (n < _n) n <<= 1; //FOR(i, 1, 2 * n) sum[i] = 0; FOR(i, 1, _n+1) sum[i+n-1] = a[i]; for (int i = n - 1; i >= 1; --i) sum[i] = max(sum[i << 1], sum[i << 1 | 1]); } void update(int i, int val) { i += n - 1; sum[i] = val; while (i > 1) { i >>= 1; sum[i] = max(sum[i << 1], sum[i << 1 | 1]); } } int query(int L, int R, int cur, int l, int r) { if (L <= l && r <= R) return sum[cur]; int mid = Mid(l, r), ret = 0; if (L <= mid) ret = max(query(L, R, lson), ret); if (R > mid) ret = max(query(L, R, rson), ret); return ret; } void debug() { FOR(i, 1, 2*n) printf("%d ", sum[i]); putchar(10); } int main() { //IN(); OUT(); int q; while (~SFF(_n, q)) { FOR(i, 1, _n + 1) SF(a[i]); build(); char op[2]; int l, r; while (q--) { //debug(); scanf("%s%d%d", op, &l, &r); if (op[0] == 'Q') PF(query(l, r, 1, 1, n)); else update(l, r); } } return 0; }lazy数组,区间更新,区间查询
POJ 3468 A Simple Problem with Integers 1641ms
#define lson cur<<1, l, mid #define rson cur<<1|1, mid+1, r LL sum[maxn<<2]; int a[maxn], lazy[maxn<<2]; void PushUp(int cur) { sum[cur] = sum[cur << 1] + sum[cur << 1 | 1]; } void build(int cur, int l, int r) { if (l == r) sum[cur] = a[l]; else { int mid = Mid(l, r); build(lson); build(rson); PushUp(cur); } } void PushDown(int cur, int cntl, int cntr) { if (lazy[cur]) { lazy[cur << 1] += lazy[cur]; lazy[cur << 1 | 1] += lazy[cur]; sum[cur << 1] += (LL)cntl*lazy[cur]; sum[cur << 1 | 1] += (LL)cntr*lazy[cur]; lazy[cur] = 0; } } void update(int L, int R, int val, int cur, int l, int r) { if (L <= l && r <= R) sum[cur] += (r - l + 1)*(LL)val, lazy[cur] += val; else { int mid = Mid(l, r); PushDown(cur, mid - l + 1, r - mid); if (L <= mid) update(L, R, val, lson); if (R > mid) update(L, R, val, rson); PushUp(cur); } } LL query(int L, int R, int cur, int l, int r) { if (L <= l && r <= R) return sum[cur]; int mid = Mid(l, r); LL ret = 0; PushDown(cur, mid - l + 1, r - mid); if (L <= mid) ret += query(L, R, lson); if (R > mid) ret += query(L, R, rson); return ret; } int main() { int n, q; while (SFF(n, q) == 2) { FOR(i, 1, n + 1) SF(a[i]); build(1, 1, n); FOR(i, 0, q) { getchar(); char op; op = getchar(); int a, b; SFF(a, b); if (op == 'Q') printf("%lld\n", query(a, b, 1, 1, n)); else { int c; SF(c); update(a, b, c, 1, 1, n); } } } return 0; }
相关文章推荐
- 2017暑假训练国庆小假期总结
- 2017暑假训练第三周周中总结
- 2017暑假训练第十四天
- 2017暑假训练第二十一天
- 2017暑假训练第四周周中总结
- 2017暑假训练第一场的一些题目
- 2017暑假训练第七天
- 2017暑假训练第十天
- 2017暑假训练第十七天
- 2015暑假训练(UVALive 5983 - 5992)线段树离线处理+dp
- 2017暑假训练第九天
- 2017暑假训练第十一天
- 2017暑假训练之KMP、扩展KMP
- 2017暑假训练第四天
- 2017暑假训练第十二天
- 2017暑假训练之树状数组
- 2017暑假集训 div1 线段树(2)
- 2017暑假训练第四周周末总结
- 2017暑假训练第十九天
- 2017暑假训练之字典树、AC自动机