您的位置:首页 > 其它

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,并且把这个格子变成这个值。

思路:

裸二维线段树,其实是自己想的写法居然和大多数版差不多……这个版写的还是太繁琐,建议直接用大白书上的版。

源码:

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