您的位置:首页 > 其它

单点更新 区间查询最值 线段树 杭电hdu1754

2017-07-11 08:27 627 查看
单点更新 区间查询最值 线段树
杭电hdu1754

初学线段树,觉得线段树美在它的递归实现,可以更新,RMQ算法可以实现区间查询最值,我不知道怎么修改

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 200007;
//线段树的节点segTree[i]存根为i的线段树的最值(用RMQ算法不能更新)
int segTree[N << 2];
void build(int rt, int l, int r) {
if (l == r) {
scanf("%d", segTree + rt);
return;
}
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
segTree[rt] = max(segTree[rt << 1], segTree[rt << 1 | 1]);
}

int query(int rt, int l, int r, int L, int R) {
//当前根rt在区间[l,r],所查询区间为[L,R]
if (L <= l && r <= R)
return segTree[rt];
int mid = l + r >> 1, Max = 0;
if (L <= mid)
Max = max(Max, query(rt << 1, l, mid, L, R));
if (R > mid)
Max = max(Max, query(rt << 1 | 1, mid + 1, r, L, R));
return Max;
}
void update(int rt, int l, int r, int pos, int val) {
//当前rt所在区间为[l,r],把原始数据中第pos个数改为val
if (l == r) {
segTree[rt] = val;
return;
}
int mid = l + r >> 1;
if (pos <= mid)
update(rt << 1, l, mid, pos, val);
else update(rt << 1 | 1, mid + 1, r, pos, val);
segTree[rt] = max(segTree[rt << 1], segTree[rt << 1 | 1]); //别忘了回溯
}

int main()
{
int n, m;
while (~scanf("%d%d", &n, &m)) {
memset(segTree, 0, sizeof segTree);
build(1, 1, n);
while (m-- > 0) {
char opt;
int a, b;
scanf(" %c%d%d", &opt, &a, &b);
if (opt == 'Q')
printf("%d\n", query(1, 1, n, a, b));
else if (opt == 'U')
update(1, 1, n, a, b);
}
}

return 0;
}

附线段树题
hdu 2795

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 200007;
int segTree[N << 2]; //segTree[i]保存节点i所在线段树的可利用的行宽的最大值
int h, w, n;
void build(int rt, int l, int r) {
segTree[rt] = w;
if (l == r) return;
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
}
int query(int rt, int l, int r, int x) {
if (l == r) {
segTree[rt] -= x;//查询时更新了
return l;
}
int mid = l + r >> 1, res;
if (segTree[rt << 1] >= x)
res = query(rt << 1, l, mid, x);
else res = query(rt << 1 | 1, mid + 1, r, x);
segTree[rt] = max(segTree[rt << 1], segTree[rt << 1 | 1]);
return res;
}
int main()
{
while (~scanf("%d%d%d", &h, &w, &n)) {
memset(segTree, 0, sizeof segTree);
h = min(h, n); //板子行数多于信息条数的用不到
build(1, 1, h);
while (n-- > 0) {
int x;
scanf("%d", &x);
if (segTree[1] < x) puts("-1");
else printf("%d\n", query(1, 1, h, x));
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: