首页 > 代码库 > 二维线段树模版

二维线段树模版


HDU 4819 二维线段树模版题

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 999999999;
const int maxn = 810;
int a[maxn][maxn];
int st_min[maxn<<2][maxn<<2];
int st_max[maxn<<2][maxn<<2];
int n;
int mi, ma;
void pushup(int rx, int rt)
{
	st_min[rx][rt] = min(st_min[rx][rt<<1], st_min[rx][rt<<1|1]);
	st_max[rx][rt] = max(st_max[rx][rt<<1], st_max[rx][rt<<1|1]);
}
void build_y(int l, int r, int rt, int flag, int rx)
{
	if(l == r)
	{
		if(flag)
		{
			int x;
			scanf("%d", &x);
			st_max[rx][rt] = st_min[rx][rt] = x;
		}
		else
		{
			st_max[rx][rt] = max(st_max[rx<<1][rt], st_max[rx<<1|1][rt]);
		 	st_min[rx][rt] = min(st_min[rx<<1][rt], st_min[rx<<1|1][rt]);
		}
		
		return;
	}
	int m = (l + r) >> 1;
	build_y(l, m, rt<<1, flag, rx);
	build_y(m+1, r, rt<<1|1, flag, rx);
	
	pushup(rx, rt);
	
}

void build_x(int l, int r, int rt)
{
	if(l == r)
	{
		build_y(1, n, 1, 1, rt);
		return;
	}
	int m = (l + r) >> 1;
	build_x(l, m, rt<<1);
	build_x(m+1, r, rt<<1|1);
	
	build_y(1, n, 1, 0, rt);
}

void update_y(int x, int l, int r, int rt, int c, int flag, int rx)
{
	if(l == r)
	{
		if(flag)
		{
			st_max[rx][rt] = st_min[rx][rt] = c;
		}
		else
		{
			st_max[rx][rt] = max(st_max[rx<<1][rt], st_max[rx<<1|1][rt]);
		 	st_min[rx][rt] = min(st_min[rx<<1][rt], st_min[rx<<1|1][rt]);
		}
		return;
	}
	int m = (l + r) >> 1;
	if(x <= m)
		update_y(x, l, m, rt<<1, c, flag, rx);
	else
		update_y(x, m+1, r, rt<<1|1, c, flag, rx);
		
	pushup(rx, rt);
}
void update_x(int x, int y, int l, int r, int rt, int c)
{
	if(l == r)
	{
		update_y(y, 1, n, 1, c, 1, rt);
		return;
	}
	int m = (l + r) >> 1;
	if(x <= m)
		update_x(x, y, l, m, rt<<1, c);
	else
		update_x(x, y, m+1, r, rt<<1|1, c);
	update_y(y, 1, n, 1, c, 0, rt);
}

void query_y(int x, int y, int l, int r, int rt, int rx)
{
	
	if(x == l && y == r)
	{
		mi = min(st_min[rx][rt], mi);
		ma = max(st_max[rx][rt], ma);
		return;
	}
	
	int m = (l + r) >> 1;
	if(y <= m)
		query_y(x, y, l, m, rt<<1, rx);
	else if(x > m)
		query_y(x, y, m+1, r, rt<<1|1, rx);
	else
	{
		query_y(x, m, l, m, rt<<1, rx);
		query_y(m+1, y, m+1, r, rt<<1|1, rx);
	}
}

void query_x(int x1, int y1, int x2, int y2, int l, int r ,int rt)
{
	//printf("%d %d\n", x1, y1);
	if(x1 == l && y1 == r)
	{
		query_y(x2, y2, 1, n, 1, rt);
		return;
	}
	int m = (l + r) >> 1;
	if(y1 <= m)
		query_x(x1, y1, x2, y2, l, m, rt<<1);
	else if(x1 > m)
		query_x(x1, y1, x2, y2, m+1, r, rt<<1|1);
	else
	{
		query_x(x1, m, x2, y2, l, m, rt<<1);
		query_x(m+1, y1, x2, y2, m+1, r, rt<<1|1);
	}
}
int main()
{
	int cas = 1;
	int T;
	scanf("%d", &T);
	while(T--)
	{
		
		scanf("%d", &n);
		/*for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				scanf("%d", &a[i][j]);
		*/
		build_x(1, n, 1);
		
		int q;
		scanf("%d", &q);
		printf("Case #%d:\n", cas++);
		while(q--)
		{
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			mi = INF;
			ma = -INF;
			int x1 = max(x-z/2, 1);
			int y1 = max(y-z/2, 1);
			int x2 = min(x+z/2, n);
			int y2 = min(y+z/2, n);
			query_x(x1, x2, y1, y2, 1, n, 1);
			printf("%d\n", (mi+ma)/2);
			update_x(x, y, 1, n, 1, (mi+ma)/2);
			//puts("dsf");
		}
	}
	return 0;
}


二维线段树模版