HDU 4819 二维线段树
来源:互联网 发布:chictopia淘宝网 编辑:程序博客网 时间:2024/05/20 11:36
HDU 4819
题目链接:
http://www.bnuoj.com/v3/problem_show.php?pid=35690
题意:
给一个初始矩阵,矩阵大小1000 * 1000。
现在有一个操作询问以(i,j)为中心的正方形(保证边长为奇数)中矩阵格子里的最大值和最小值,输出(max+min)/2,并且把这个格子变成这个值。
思路:
裸二维线段树,其实是自己想的写法居然和大多数版差不多……这个版写的还是太繁琐,建议直接用大白书上的版。
源码:
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <iostream>#include <string>#include <vector>using namespace std;#define inf (1000000007)typedef pair<int,int> pii;const int MAXN = 800 + 5;int mmin[MAXN * 4][MAXN * 4], mmax[MAXN * 4][MAXN * 4];int a[MAXN][MAXN];int n;int temp;pii change(pii a, pii b){ pii ans; ans.first = min(a.first, b.first); ans.second = max(a.second, b.second); return ans;}void push_upx(int ox, int oy){ mmin[ox][oy] = min(mmin[ox << 1][oy], mmin[(ox << 1) + 1][oy]); mmax[ox][oy] = max(mmax[ox << 1][oy], mmax[(ox << 1) + 1][oy]);}void push_upy(int ox, int oy){ mmin[ox][oy] = min(mmin[ox][oy << 1], mmin[ox][(oy << 1) + 1]); mmax[ox][oy] = max(mmax[ox][oy << 1], mmax[ox][(oy << 1) + 1]);}void buildy(int ox, int lx, int rx, int oy, int ly, int ry){ temp = max(temp, oy); if(lx == rx){ if(ly == ry) mmin[ox][oy] = mmax[ox][oy] = a[lx][ly]; else{ int mid = (ly + ry) >> 1; buildy(ox, lx, rx, (oy << 1), ly, mid); buildy(ox, lx, rx, (oy << 1) + 1, mid + 1, ry); push_upy(ox, oy); } } else{ if(ly == ry) push_upx(ox, oy); else{ int mid = (ly + ry) >> 1; buildy(ox, lx, rx, (oy << 1), ly, mid); buildy(ox, lx, rx, (oy << 1) + 1, mid + 1, ry); push_upx(ox, oy); } }}void buildx(int ox, int lx, int rx){ if(lx != rx){ int mid = (lx + rx) >> 1; buildx(ox << 1, lx, mid); buildx((ox << 1) + 1, mid + 1, rx); } buildy(ox, lx, rx, 1, 1, n);}void updatey(int ox, int lx, int rx, int oy, int ly, int ry, int y, int val){// printf("updatey ox = %d, oy = %d, ly = %d, ry = %d, y = %d, val = %d\n", ox, oy, ly, ry, y, val); if(lx == rx){ if(ly == ry) mmin[ox][oy] = mmax[ox][oy] = val; else{ int mid = (ly + ry) >> 1; if(y <= mid) updatey(ox, lx, rx, oy << 1, ly, mid, y, val); else updatey(ox, lx, rx, (oy << 1) + 1, mid + 1, ry, y, val); push_upy(ox, oy); } } else{ if(ly == ry) push_upx(ox, oy); else{ int mid = (ly + ry) >> 1; if(y <= mid) updatey(ox, lx, rx, oy << 1, ly, mid, y, val); else updatey(ox, lx, rx, (oy << 1) + 1, mid + 1, ry, y, val); push_upy(ox, oy); } }}void updatex(int ox, int lx, int rx, int x, int y, int val){// printf("udpatex ox = %d, lx = %d, rx = %d, x = %d, y = %d, val = %d\n", ox, lx, rx, x, y, val);// if(val == 6) printf("ox = %d, lx = %d, rx = %d") if(lx == rx){ updatey(ox, lx, rx, 1, 1, n, y, val); } else{ int mid = (lx + rx) >> 1; if(x <= mid) updatex(ox << 1, lx, mid, x, y, val); else updatex((ox << 1) + 1, mid + 1, rx, x, y, val); updatey(ox, lx, rx, 1, 1, n, y, val); }}pii queryy(int ox, int oy, int ly, int ry, int y, int L){ pii ans = make_pair(inf, -inf); int y1 = y - L / 2; int y2 = y + L / 2; if(ly >= y1 && ry <= y2) ans = make_pair(mmin[ox][oy], mmax[ox][oy]); else{ int mid = (ly + ry) >> 1; if(y1 <= mid) ans = change(ans, queryy(ox, oy << 1, ly, mid, y, L)); if(y2 > mid) ans = change(ans, queryy(ox, (oy << 1) + 1, mid + 1, ry, y, L)); } return ans;}pii queryx(int ox, int lx, int rx, int x, int y, int L){ pii ans = make_pair(inf, -inf); int x1 = x - L / 2; int x2 = x + L / 2; if(lx >= x1 && rx <= x2) ans = queryy(ox, 1, 1, n, y, L); else{ int mid = (lx + rx) >> 1; if(x1 <= mid) ans = change(ans, queryx(ox << 1, lx, mid, x, y, L)); if(x2 > mid) ans = change(ans, queryx((ox << 1) + 1, mid + 1, rx, x, y, L)); } return ans;}int main(){ int T; scanf("%d", &T); for(int cas = 1 ; cas <= T ; cas++){ scanf("%d", &n); for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= n ; j++) scanf("%d", &a[i][j]); temp = 0; buildx(1, 1, n); int q; printf("Case #%d:\n", cas); scanf("%d", &q); while(q--){ int u, v, L; scanf("%d%d%d", &u, &v, &L); pii ans = queryx(1, 1, n, u, v, L);// printf("ans.first = %d, ans.second = %d\n", ans.first, ans.second); a[u][v] = (ans.second + ans.first) / 2; printf("%d\n", a[u][v]); updatex(1, 1, n, u, v, a[u][v]);// for(int i = 1 ; i <= 5 ; i++){// for(int j = 1 ; j <= 5 ; j++) printf("%d ", mmax[i][j]);// printf("\n");// }// printf("\n");// for(int i = 1 ; i <= 5 ; i++){// for(int j = 1 ; j <= 5 ; j++) printf("%d ", mmin[i][j]);// printf("\n");// } } } return 0;}
0 0
- HDU 4819 二维线段树
- HDU 4819 二维线段树
- HDU 4819 二维线段树
- HDU 4819 二维线段树
- hdu 4819 二维线段树
- hdu 4819 Mosaic (二维线段树)
- HDU-4819-Mosaic(二维线段树)
- hdu 4819 二维线段树点更新
- 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 --二维线段树(树套树)
- ubuntu中安装和卸载apache2、php、mysql
- 算法导论第三版习题4.4
- 不重复打印排序数组中相加和为给定值的所有二元三元组
- mybatis学习
- 随笔知识小点总结
- HDU 4819 二维线段树
- HDU 1823 二维线段树
- LightOj 1081 二维线段树
- 一对多和多对多的区别
- matlab读jpeg图像--jpeg toolbox的使用
- PAT 1005
- 学习kNN算法的感受
- equals和==的区分
- JavaScript函数补完:sort()排序