Mosaic HDU
来源:互联网 发布:神盾阅读器软件 编辑:程序博客网 时间:2024/05/22 07:55
题目链接:Mosaic HDU - 4819
题目大意
一个n*n的矩阵, 让你求其中一个矩形区域中的最大值和最小值, 并更新其中的一个位置的值
思路
二维线段树
代码
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <set>#include <queue>#include <vector>using namespace std;const int maxn = 1e3 + 10, inf = 0x3f3f3f3f;int locx[maxn], locy[maxn];//x坐标和y坐标在线段树中对应的叶子节点的下标struct Nodey//代表一个点{ int l, r, ma, mi;};struct Nodex//代表一条x方向的一维线段树{ int l, r; Nodey sty[maxn << 2]; void build(int rt, int L, int R) { sty[rt].l = L; sty[rt].r = R; sty[rt].ma = -inf; sty[rt].mi = inf; if (L == R) { locy[L] = rt; return ; } int mid = (L + R) >> 1; build(rt << 1, L, mid); build((rt << 1) | 1, mid + 1, R); } int queryMin(int rt, int L, int R) { if (sty[rt].l == L && sty[rt].r == R) return sty[rt].mi; int mid = (sty[rt].l + sty[rt].r) >> 1; if (mid < L) return queryMin((rt << 1) | 1, L, R); else if (mid >= R) return queryMin(rt << 1, L, R); else return min(queryMin((rt << 1) | 1, mid+1, R), queryMin(rt << 1, L, mid)); } int queryMax(int rt, int L, int R) { if (sty[rt].l == L && sty[rt].r == R) return sty[rt].ma; int mid = (sty[rt].l + sty[rt].r) >> 1; if (mid < L) return queryMax((rt << 1) | 1, L, R); else if (mid >= R) return queryMax(rt << 1, L, R); else return max(queryMax((rt << 1) | 1, mid+1, R), queryMax(rt << 1, L, mid)); }} stx[maxn << 2];int n;void build(int rt, int l, int r){ stx[rt].l = l; stx[rt].r = r; stx[rt].build(1, 1, n); if (l == r) { locx[l] = rt; return ; } int mid = (l + r) >> 1; build(rt << 1, l, mid); build((rt << 1) | 1, mid + 1, r);}void update(int x, int y, int v){ x = locx[x], y = locy[y]; stx[x].sty[y].mi = stx[x].sty[y].ma = v; for (int i = x; i; i >>= 1) { for (int j = y; j; j >>= 1) { if (i == x && j == y) continue; if (j == y) // x, y -> 2x, y, when double the length of x { stx[i].sty[j].mi = min(stx[i << 1].sty[j].mi, stx[(i << 1) | 1].sty[j].mi); stx[i].sty[j].ma = max(stx[i << 1].sty[j].ma, stx[(i << 1) | 1].sty[j].ma); } else { stx[i].sty[j].mi = min(stx[i].sty[j << 1].mi, stx[i].sty[(j << 1) | 1].mi); stx[i].sty[j].ma = max(stx[i].sty[j << 1].ma, stx[i].sty[(j << 1) | 1].ma); } } }}int queryMin(int rt, int x1, int x2, int y1, int y2){ if (stx[rt].l == x1 && stx[rt].r == x2) return stx[rt].queryMin(1, y1, y2); int mid = (stx[rt].l + stx[rt].r) >> 1; if (x1 > mid) return queryMin((rt << 1) | 1, x1, x2, y1, y2); else if (x2 <= mid) return queryMin(rt << 1, x1, x2, y1, y2); else return min(queryMin((rt << 1) | 1, mid+1, x2, y1, y2), queryMin(rt << 1, x1, mid, y1, y2));}int queryMax(int rt, int x1, int x2, int y1, int y2){ if (stx[rt].l == x1 && stx[rt].r == x2) return stx[rt].queryMax(1, y1, y2); int mid = (stx[rt].l + stx[rt].r) >> 1; if (x1 > mid) return queryMax((rt << 1) | 1, x1, x2, y1, y2); else if (x2 <= mid) return queryMax(rt << 1, x1, x2, y1, y2); else return max(queryMax((rt << 1) | 1, mid+1, x2, y1, y2), queryMax(rt << 1, x1, mid, y1, y2));}int main(){ int T, cas = 1; for (scanf("%d", &T); T; --T) { printf("Case #%d:\n", cas++); scanf("%d", &n); build(1, 1, n); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { int t; scanf("%d", &t); update(i, j, t); } } int q, x, y, L; scanf("%d", &q); while (q--) { scanf("%d%d%d", &x, &y, &L); int x1 = max(x - L / 2, 1); int x2 = min(x + L / 2, n); int y1 = max(y - L / 2, 1); int y2 = min(y + L / 2, n); int Max = queryMax(1, x1, x2, y1, y2); int Min = queryMin(1, x1, x2, y1, y2); int t = (Max + Min) / 2; printf("%d\n", t); update(x, y, t); } } return 0;}
网上的一个模板
struct Nodey { int ly, ry, val, Max, Min, sum;//元素 最大值 最小值 元素和};int nx, ny;//横长 竖长int posx[MAXN], posy[MAXN];struct Nodex { int lx, rx; Nodey treey[MAXN<<2]; void Build_y(int o, int l, int r) { treey[o].ly = l; treey[o].ry = r; treey[o].Max = 0; treey[o].Min = INF; treey[o].sum = 0; treey[o].val = 0; if(l == r) { posy[l] = o; return ; } int mid = (l + r) >> 1; Build_y(ll, l, mid); Build_y(rr, mid+1, r); } int Query_y(int o, int y1, int y2, int op) { if(treey[o].ly == y1 && treey[o].ry == y2) { if(op == 0) return treey[o].Max; if(op == 1) return treey[o].Min; if(op == 2) return treey[o].sum; } int mid = (treey[o].ly + treey[o].ry) >> 1; if(y2 <= mid) return Query_y(ll, y1, y2, op); else if(y1 > mid) return Query_y(rr, y1, y2, op); else { if(op == 0) return max(Query_y(ll, y1, mid, op), Query_y(rr, mid+1, y2, op)); if(op == 1) return min(Query_y(ll, y1, mid, op), Query_y(rr, mid+1, y2, op)); if(op == 2) return Query_y(ll, y1, mid, op) + Query_y(rr, mid+1, y2, op); } }};Nodex treex[MAXN<<2];void Build_x(int o, int l, int r) { treex[o].lx = l; treex[o].rx = r; treex[o].Build_y(1, 1, ny); if(l == r) { posx[l] = o; return ; } int mid = (l + r) >> 1; Build_x(ll, l, mid); Build_x(rr, mid+1, r);}int Query_x(int o, int x1, int x2, int y1, int y2, int op) { if(treex[o].lx == x1 && treex[o].rx == x2) { return treex[o].Query_y(1, y1, y2, op); } int mid = (treex[o].lx + treex[o].rx) >> 1; if(x2 <= mid) return Query_x(ll, x1, x2, y1, y2, op); else if(x1 > mid) return Query_x(rr, x1, x2, y1, y2, op); else { if(op == 0) return max(Query_x(ll, x1, mid, y1, y2, op), Query_x(rr, mid+1, x2, y1, y2, op)); if(op == 1) return min(Query_x(ll, x1, mid, y1, y2, op), Query_x(rr, mid+1, x2, y1, y2, op)); if(op == 2) return Query_x(ll, x1, mid, y1, y2, op) + Query_x(rr, mid+1, x2, y1, y2, op); }}void PushUpy(int x, int y) { treex[x].treey[y].Max = max(treex[x].treey[y<<1].Max, treex[x].treey[y<<1|1].Max); treex[x].treey[y].Min = min(treex[x].treey[y<<1].Min, treex[x].treey[y<<1|1].Min); treex[x].treey[y].sum = treex[x].treey[y<<1].sum + treex[x].treey[y<<1|1].sum;}void PushUpx(int x, int y) { treex[x].treey[y].Max = max(treex[x<<1].treey[y].Max, treex[x<<1|1].treey[y].Max); treex[x].treey[y].Min = min(treex[x<<1].treey[y].Min, treex[x<<1|1].treey[y].Min); treex[x].treey[y].sum = treex[x<<1].treey[y].sum + treex[x<<1|1].treey[y].sum;}void Change(int x, int y, int v) { treex[x].treey[y].Max = v; treex[x].treey[y].Min = v; treex[x].treey[y].sum = v; treex[x].treey[y].val = v;}void Update(int x, int y, int v) {//单点更新 for(int i = posx[x]; i ; i >>= 1) { for(int j = posy[y]; j ; j >>= 1) { if(i == posx[x] && j == posy[y]) { Change(posx[x], posy[y], v); continue; } PushUpy(i, j); } if(i == posx[x]) continue; for(int j = posy[y]; j ; j >>= 1) { PushUpx(i, j); } }}int Sum(int x, int y) {//求 (x, y)对应节点到根路径的元素之和 int sum = 0; for(int i = posx[x]; i ; i >>= 1) { for(int j = posy[y]; j ; j >>= 1) { sum += treex[i].treey[j].val; } } return sum;}
阅读全文
0 0
- Mosaic HDU
- hdu 4819 Mosaic
- HDU 4819 Mosaic
- HDU-4819-Mosaic
- hdu 4819 Mosaic
- MOSAIC
- mosaic
- hdu 4819 Mosaic (二维线段树)
- HDU-4819-Mosaic(二维线段树)
- HDU 4819 Mosaic 二维线段树
- HDU 4819 Mosaic(二维线段树)
- HDU 4819 Mosaic 二维线段树
- hdu 4819 Mosaic【二维线段树】
- HDU 4819 Mosaic 二维线段树
- hdu 4819 Mosaic(二维线段树)
- HDU 4819 Mosaic 二维线段树
- HDU 4819 Mosaic 二维线段树
- HDU 4819 Mosaic (二维线段树)
- js向java后台传汉字乱码的解决方法
- C++程序设计(下)第一周
- vue组件(二)
- windows 7下硬盘安装Ubuntu遇到的问题
- React Native 网络请求
- Mosaic HDU
- mysql 查询中文乱码
- 史上最全面的CentOS 7 之 redis 安装
- 复杂选择器 内容生成 多列 CSSHack(浏览器兼容)
- Android_XRecyclerView上拉下拉加载数据
- Appium最新的Java client库废弃了swipe等函数后,用TouchAction实现各种手势操作
- java中的socket编程
- 流与文件
- Java知识点概括