HDU 4819 二维线段树
2016-01-18 18:55
459 查看
HDU 4819
题目链接:
http://www.bnuoj.com/v3/problem_show.php?pid=35690
题意:
给一个初始矩阵,矩阵大小1000 * 1000。
现在有一个操作询问以(i,j)为中心的正方形(保证边长为奇数)中矩阵格子里的最大值和最小值,输出(max+min)/2,并且把这个格子变成这个值。
思路:
裸二维线段树,其实是自己想的写法居然和大多数版差不多……这个版写的还是太繁琐,建议直接用大白书上的版。
源码:
题目链接:
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; }
相关文章推荐
- 使用对象集合(通过Foundation框架使用OC处理字典,集合)
- 在使用jfreechart中需要注意的问题
- 数据泵--导入时自动创建用户
- Codeforces Gym 100531I Instruction 构造
- ubuntu中安装和卸载apache2、php、mysql
- POJ 2155 二维线段树
- 我的算法学习之路
- 算法导论第三版习题4.4
- s5pv210编译qt
- 获取文章的字数或则字符数
- 反编译[学习笔记]
- DEDE如何文章页调用相关文章列表
- cocos2d-x中ScrollView内的元素位置问题
- 通过Windows Media Player控件获取音频文件的时长
- 织梦安装时dede不能写入 怎么设置啊
- 孩子冷不冷?一指辨寒热!
- 操作符
- FSM(状态机)、HFSM(分层状态机)、BT(行为树)的区别
- 企业库判断数据库连接类型
- dede后台怎么进入 DEDE如何进入系统管理后台