Poj 4047 Garden /2012金华邀请赛D题(线段树)
2012-05-09 22:08
465 查看
题意:给出长度为200000的数列,进行200000次下列操作:
0 x y 将x的值置为y
1 x y 交换x和y的值
2 x y 求[x,y]区间内和最大的一个连续的长度为k的区间(y-x>k)
解法:显而易见的线段树开始一直想维护每个区间的最大k区间,但是一直想不出怎么维护父节点和子节点的关系。估计如果实在现场会困死在此题。。。
于是需要转换一下思维,把点当做区间把区间当做一个点,具体来说,线段树上每个叶子节点i的值为数列i~i+k-1的和,这样求[x,y]的最大值就转换成了求[x,y-k+1]区间的最大值,对于每次对于点的更新,更新它能影响到的所有长为k的区间,即 [x - k + 1,x];这种思想经常用到,比如前几天碰到的一道alibaba校园赛费用流问题(hdu4106)
PS:再次感慨线段树的变化多端,虽然种过二三十颗树了还是驾驭不了,这几天继续种。。。
0 x y 将x的值置为y
1 x y 交换x和y的值
2 x y 求[x,y]区间内和最大的一个连续的长度为k的区间(y-x>k)
解法:显而易见的线段树开始一直想维护每个区间的最大k区间,但是一直想不出怎么维护父节点和子节点的关系。估计如果实在现场会困死在此题。。。
于是需要转换一下思维,把点当做区间把区间当做一个点,具体来说,线段树上每个叶子节点i的值为数列i~i+k-1的和,这样求[x,y]的最大值就转换成了求[x,y-k+1]区间的最大值,对于每次对于点的更新,更新它能影响到的所有长为k的区间,即 [x - k + 1,x];这种思想经常用到,比如前几天碰到的一道alibaba校园赛费用流问题(hdu4106)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; public class Garden { class SegTree { class node { int left, right; int max, add; int mid() { return (left + right) >> 1; } } node tree[]=new node[600010]; void init(int left, int right, int idx, int a[]) { tree[idx] = new node(); tree[idx].left = left; tree[idx].right = right; if (left == right) { tree[idx].max = a[left]; return; } int mid = tree[idx].mid(); init(left, mid, idx << 1, a); init(mid + 1, right, (idx << 1) | 1, a); tree[idx].max = Math.max(tree[idx << 1].max, tree[(idx << 1) | 1].max); } void pushdown(int idx) { if (tree[idx].add == 0) return; int k = tree[idx].add; tree[idx].max += k; tree[idx].add = 0; if (tree[idx].left == tree[idx].right) return; tree[idx << 1].add += k; tree[(idx << 1) | 1].add += k; } void update(int left, int right, int idx, int v) { pushdown(idx); if (left <= tree[idx].left && right >= tree[idx].right) { tree[idx].add += v; return; } int mid = tree[idx].mid(); if (left <= mid) update(left, right, idx << 1, v); if (right > mid) update(left, right, (idx << 1)|1, v); pushdown(idx<<1); pushdown((idx<<1)|1); tree[idx].max = Math.max(tree[idx << 1].max, tree[(idx << 1)|1].max); } int query(int left, int right, int idx) { pushdown(idx); if (tree[idx].left == left && tree[idx].right == right) { return tree[idx].max; } int mid = tree[idx].mid(); if (right <= mid) return query(left, right, idx << 1); else if (left > mid) return query(left, right, (idx << 1) | 1); else return Math.max(query(left, mid, idx << 1), query(mid + 1, right, (idx << 1) | 1)); } } SegTree st = new SegTree(); int sum[]=new int[200010], arr[]=new int[200010], p[]=new int[200010]; StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); int next() throws IOException { in.nextToken(); return (int) in.nval; } void run() throws IOException { int cas = next(); while (cas-- > 0) { int n = next(); int m = next(); int k = next(); for (int i = 1; i <= n; i++) { p[i] = next(); sum[i] = p[i] + sum[i - 1]; } for (int i = 1; i + k - 1 <= n; i++) arr[i] = sum[i + k - 1] - sum[i - 1]; st.init(1, n - k + 1, 1, arr); while (m-- > 0) { int op =next(); int x = next(); int y = next(); if (op == 0) { int from = x - k + 1; if (from < 1) from = 1; int key = y - p[x]; p[x] = y; st.update(from, x, 1, key); } if (op == 1) { int from=x-k+1; if(from<1) from=1; int temp=p[x]; int key=p[y]-p[x]; p[x]=p[y]; st.update(from, x, 1, key); from=y-k+1; if(from<1) from=1; key=temp-p[y]; p[y]=temp; st.update(from, y, 1, key); } if(op==2) { int to=y-k+1; System.out.println(st.query(x, to, 1)); } } } } public static void main(String[] args) throws IOException { new Garden().run(); } }
PS:再次感慨线段树的变化多端,虽然种过二三十颗树了还是驾驭不了,这几天继续种。。。
相关文章推荐
- poj 4047 Garden 2012金华邀请赛 线段树
- poj 4047 Garden(线段树,伤!12年金华邀请赛D题)
- POJ 4045 Power Station 2012金华邀请赛B题(树形DP)
- POJ 2012金华邀请赛 (持续更新)
- poj 4052 Hrinity 2012 金华邀请赛 AC自动机 DFA
- poj 4047 Garden 2012金华赛区 (成段更新+区间最值)
- poj 4047金华邀请赛 D题 (线段树+lazy优化)
- 2012金华邀请赛 Problem D. Garden 线段树题目
- 2012金华邀请赛总结
- POJ 4052 金华邀请赛I题
- 2012金华邀请赛
- poj 4047 Garden(线段树)
- POJ - 4047 Garden(线段树成段更新,查询最值)
- 2012金华邀请赛解题报告
- poj 4044 Score Sequence(暴力,12年金华邀请赛A题)
- poj 4047 Garden 线段树lazy标记与成段更新
- POJ 4047 Garden (线段树 - 区间增减、区间查询) -- 解题报告
- Power Station(2012 acm-icpc 金华邀请赛 B题 )树型dp
- 金华邀请赛B题poj 4046(spfa求最短路)
- POJ 4052 Hrinity (金华邀请赛I题) AC自动机