POJ - 4047 Garden(线段树成段更新,查询最值)
来源:互联网 发布:炼数成金 大数据分析师 编辑:程序博客网 时间:2024/05/22 05:22
题意:含n个元素的序列 ,有q个操作。
操作( p x y)有三种:
0 x y :把第x个的值改为y
1 x y:交换第x个和第y个的值
2 x y:问区间[x,y]里面连续k个的子序列的最大和
思路:先处理序列,SumK[i]表示从i开始的k个数的和,然后线段树建树,成段更新,查询。更新只要处理成对区间最值得加减就可以了。
成段更新还是不熟悉,于是顺便做了 POJ - 3468 A Simple Problem with Integers,也是成段更新,查询为区间元素和,有些不同。
#include <iostream>#include <cstdio>using namespace std;#define max(a,b) a>b?a:bconst int MAXN = 200000 + 1000;int num[MAXN];int sumK[MAXN];int sum[MAXN];int father[MAXN];struct node{int l, r;int Max;int lazy;}tree[MAXN*3];inline void pushUp(int i){int ls = i << 1, rs = ls + 1;tree[i].Max = max(tree[ls].Max, tree[rs].Max);}void pushDown(int i){if (tree[i].lazy){int ls = i << 1, rs = ls + 1;tree[ls].lazy += tree[i].lazy;tree[rs].lazy += tree[i].lazy;tree[ls].Max += tree[i].lazy;tree[rs].Max += tree[i].lazy;tree[i].lazy = 0;}}void build(int l, int r, int i){tree[i].lazy = 0;tree[i].l = l;tree[i].r = r;if (l == r){tree[i].Max = sumK[l];father[l] = i;return;}int ls = i << 1, rs = ls + 1;int m = (l + r) >> 1;build(l, m, ls);build(m + 1, r, rs);pushUp(i);}void update(int l, int r, int i, int v){if (l <= tree[i].l && r >= tree[i].r){tree[i].lazy += v;tree[i].Max += v;return;}pushDown(i);int m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1;if (r <= m) update(l, r, ls, v);else if (l > m) update(l, r , rs, v);else{update(l, m, ls, v);update(m + 1, r, rs, v);}pushUp(i);}int query(int l, int r, int i){if (l<=tree[i].l && r>=tree[i].r)return tree[i].Max;pushDown(i);int m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1;if (r <= m)return query(l, r, ls);else if (l > m)return query(l, r, rs);elsereturn max(query(l, m, ls), query(m + 1, r, rs));}int main(){int casen;scanf("%d", &casen);while (casen--){int n, m, k;scanf("%d%d%d", &n, &m, &k);for (int i = 1; i <= n; i++)scanf("%d", &num[i]);int len = n - k + 1;sum[0] = 0;for (int i = 1; i <= n; i++)sum[i] = sum[i - 1] + num[i];for (int i = 1; i <= len; i++)sumK[i] = sum[i + k - 1] - sum[i - 1];build(1, len, 1);int op, x, y;while (m--){scanf("%d%d%d", &op, &x, &y);if (op == 0){int add = y - num[x];num[x] = y;int s = max(x - k + 1, 1);int e = x;update(s, e, 1, add);}else if (op == 1){int add1 = num[x] - num[y];int add2 = num[y] - num[x];int s1 = max(x - k + 1, 1);int s2 = max(y - k + 1, 1);int e1 = x;int e2 = y;int temp = num[x];num[x] = num[y];num[y] = temp;update(s1, e1, 1, add2);update(s2, e2, 1, add1);}else{int s = x;int e = max(y - k + 1, 1);int ans = query(s, e, 1);printf("%d\n", ans);}}}}
0 0
- POJ - 4047 Garden(线段树成段更新,查询最值)
- poj 4047 Garden 2012金华赛区 (成段更新+区间最值)
- POJ 4047 Garden 线段树
- POJ 4047 Garden (线段树)
- poj 4047 Garden 线段树lazy标记与成段更新
- POJ 3237Tree(树链剖分-线段树点更新-区间更新-区间最值查询-入边)
- POJ 4047 Garden (线段树 - 区间增减、区间查询) -- 解题报告
- poj 4047 Garden(线段树,伤!12年金华邀请赛D题)
- Poj 4047 Garden /2012金华邀请赛D题(线段树)
- poj 4047 Garden 2012金华邀请赛 线段树
- POJ【4047】——Problem D. Garden 线段树
- 线段树大模板(区间更新,单点更新,查询区间最值等等)
- poj 4047 Garden
- POJ 4047 Garden
- POJ 4047: Garden
- POJ 4047 Garden
- POJ-3468(线段树区间更新区间查询)
- POJ 2777 Count Color(线段树,区间更新,查询)
- [高效算法 deque运用]UVa120 - Stacks of Flapjacks
- [LeetCode 205] Isomorphic Strings
- vector容器v1、v2之间相互赋值的三种方法及易错点详解
- IOS开发之实现App消息推送
- [Hash思想]UVa1152 - 4 Values whose Sum is 0
- POJ - 4047 Garden(线段树成段更新,查询最值)
- iOS实现倒计时功能
- [问题分解]UVa11054 - Wine trading in Gergovia
- [等价转换]UVa11054 - Wine trading in Gergovia
- [极角排序 扫描法]UVa1606 - Amphiphilic Carbon Molecules
- HDU 4123 Bob’s Race(树形DP+RMQ)
- POJ - 3468 A Simple Problem with Integers(线段树成段更新,查询区间和)
- C++英文单词统计小程序
- java 内存模型