HDU 4819 Mosaic(13年长春现场 二维线段树)

HDU 4819 Mosaic

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819

题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l),求出该区域内的最大值(A)和最小值(B),输出(A+B)/2,并用这个值更新矩阵[x,y]的值

思路:裸的二维线段树,用树套树实现

# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std; # define lson l,m,rt<<
# define rson m+,r,rt<<|
# define MAXN
int xL,xR,yL,yR,val;
int maxv,minv;
int Max[MAXN<<][MAXN<<],Min[MAXN<<][MAXN<<];
int N,mat[MAXN][MAXN]; void PushUp(int xrt,int rt)
{
Max[xrt][rt]=max(Max[xrt][rt<<],Max[xrt][rt<<|]);
Min[xrt][rt]=min(Min[xrt][rt<<],Min[xrt][rt<<|]);
} void BuildY(int xrt,int x,int l,int r,int rt)
{
int m;
if(l==r)
{
if(x!=-) Max[xrt][rt]=Min[xrt][rt]=mat[x][l];
else
{
Max[xrt][rt]=max(Max[xrt<<][rt],Max[xrt<<|][rt]);
Min[xrt][rt]=min(Min[xrt<<][rt],Min[xrt<<|][rt]);
}
return;
}
m=(l+r)>>;
BuildY(xrt,x,lson);
BuildY(xrt,x,rson);
PushUp(xrt,rt);
} void BuildX(int l,int r,int rt)
{
int m;
if(l==r)
{
BuildY(rt,l,,N,);
return;
}
m=(l+r)>>;
BuildX(lson);
BuildX(rson);
BuildY(rt,-,,N,);
} void UpdateY(int xrt,int x,int l,int r,int rt)
{
int m;
if(l==r)
{
if(x!=-) Max[xrt][rt]=Min[xrt][rt]=val;
else
{
Max[xrt][rt]=max(Max[xrt<<][rt],Max[xrt<<|][rt]);
Min[xrt][rt]=min(Min[xrt<<][rt],Min[xrt<<|][rt]);
}
return;
}
m=(l+r)>>;
if(yL<=m) UpdateY(xrt,x,lson);
else UpdateY(xrt,x,rson);
PushUp(xrt,rt);
} void UpdateX(int l,int r,int rt)
{
int m;
if(l==r)
{
UpdateY(rt,l,,N,);
return;
}
m=(l+r)>>;
if(xL<=m) UpdateX(lson);
else UpdateX(rson);
UpdateY(rt,-,,N,);
} void QueryY(int xrt,int l,int r,int rt)
{
int m;
if(yL<=l&&yR>=r)
{
minv=min(minv,Min[xrt][rt]);
maxv=max(maxv,Max[xrt][rt]);
return;
}
m=(l+r)>>;
if(yL<=m) QueryY(xrt,lson);
if(yR>m) QueryY(xrt, rson);
} void QueryX(int l,int r,int rt)
{
int m;
if(xL<=l&&xR>=r)
{
QueryY(rt,,N,);
return;
}
m=(l+r)>>;
if(xL<=m) QueryX(lson);
if(xR>m) QueryX(rson);
} int main()
{
//freopen("in.txt","r",stdin);
int i,j,q,cas,T,x,y,l;
char op[];
scanf("%d",&T);
for(cas=;cas<=T;cas++)
{
scanf("%d",&N);
for(i=;i<=N;i++)
for(j=;j<=N;j++)
scanf("%d",&mat[i][j]);
BuildX(,N,);
scanf("%d",&q);
printf("Case #%d:\n",cas);
while(q--)
{
scanf("%d%d%d",&x,&y,&l);
l=(l+)/;
xL=max(,x-l+),xR=min(N,x+l-);
yL=max(,y-l+),yR=min(N,y+l-);
minv=<<,maxv=-(<<);
QueryX(,N,);
val=(maxv+minv)/;
xL=x,yL=y;
printf("%d\n",val);
UpdateX(,N,);
}
}
return ;
}

HDU 4819

上一篇:ios晃动检测


下一篇:剑指offer26:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。