您的位置:首页 > 其它

uva 11297 Census

2014-09-21 20:46 756 查看
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2272

题目描述:输入一个矩阵,要求支持两个操作,1. 查询某个矩形区域内的最大值及最小值 2. 将 x y 位置的数改为 v

解题思路:我是根据刘汝佳的白书上的说明做的这道题,以前从来不会二维线段树,今天终于写了一发,还是感觉常数比较大。。。虽然白书上说这种写法已经很快了

建议自己写一发,这样才能清除具体的细节,不然只是知道大概是不行的

二维线段树是一维线段树的扩展,二维线段树每个节点维护一棵线段树。这样对于一个x方向的节点,维护的线段树是维护的从l 行到r 行的所有信息,在build 和update的时候要注意行方向的更新,详见代码!!

//#pragma comment(linker,"/STACK:102400000,102400000")
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define ll long long
#define db double
#define PB push_back
#define lson k<<1
#define rson k<<1|1
using namespace std;

const int N = 505;
const int INF = 1000000000;
int a

;
struct SegmentTree2D
{
int n,m;
int max_val[N<<2][N<<2],min_val[N<<2][N<<2];
int max_res,min_res;//-INF INF
int X1,X2,Y1,Y2,x,val,X,Y,xx;
bool isleaf;
void queryY(int k,int l,int r)
{
if(l>=Y1&&r<=Y2)
{
max_res=max(max_res,max_val[x][k]);
min_res=min(min_res,min_val[x][k]);
return;
}
int mid=(l+r)>>1;
if(Y1<=mid) queryY(lson,l,mid);
if(Y2>mid) queryY(rson,mid+1,r);
}
void queryX(int k,int l,int r)
{
if(l>=X1&&r<=X2)
{
x=k;
queryY(1,1,m);
return;
}
int mid=(l+r)>>1;
if(X1<=mid) queryX(lson,l,mid);
if(X2>mid) queryX(rson,mid+1,r);
}
void updateY(int k,int l,int r)
{
if(l==r)
{
if(isleaf)
max_val[x][k]=min_val[x][k]=val;
else
max_val[x][k]=max(max_val[x<<1][k],max_val[x<<1|1][k]),  // x<<1 not lson!!!
min_val[x][k]=min(min_val[x<<1][k],min_val[x<<1|1][k]);  // x<<1|1 not rson!!
return;
}
int mid=(l+r)>>1;
if(Y<=mid) updateY(lson,l,mid);
if(Y>mid) updateY(rson,mid+1,r);
max_val[x][k]=max(max_val[x][lson],max_val[x][rson]);
min_val[x][k]=min(min_val[x][lson],min_val[x][rson]);
}
void updateX(int k,int l,int r)
{
if(l==r)
{
x=k,isleaf=true;
updateY(1,1,m);
return;
}
int mid=(l+r)>>1;
if(X<=mid) updateX(lson,l,mid);
if(X>mid) updateX(rson,mid+1,r);
x=k,isleaf=false;
updateY(1,1,m);
}
void buildY(int k,int l,int r)
{
if(l==r)
{
if(isleaf)
max_val[x][k]=min_val[x][k]=a[xx][l];
else
max_val[x][k]=max(max_val[x<<1][k],max_val[x<<1|1][k]),  // be careful
min_val[x][k]=min(min_val[x<<1][k],min_val[x<<1|1][k]);  //
return;
}
int mid=(l+r)>>1;
buildY(lson,l,mid),buildY(rson,mid+1,r);
max_val[x][k]=max(max_val[x][lson],max_val[x][rson]);
min_val[x][k]=min(min_val[x][lson],min_val[x][rson]);
}
void buildX(int k,int l,int r)
{
if(l==r)
{
x=k,isleaf=true;
xx=l;
buildY(1,1,m);
return;
}
int mid=(l+r)>>1;
buildX(lson,l,mid),buildX(rson,mid+1,r);
x=k,isleaf=false;
buildY(1,1,m);
}
} tr;

int main()
{
#ifdef PKWV
freopen("in.in","r",stdin);
#endif // PKWV
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
tr.n=n,tr.m=m;
tr.buildX(1,1,n);
int Q;
scanf("%d",&Q);
while(Q--)
{
char ch[10];
scanf("%s",ch);
if(ch[0]=='q')
{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
tr.max_res=-INF,tr.min_res=INF;
tr.X1=x1,tr.X2=x2,tr.Y1=y1,tr.Y2=y2;
tr.queryX(1,1,n);
printf("%d %d\n",tr.max_res,tr.min_res);
}else
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
tr.X=x,tr.Y=y,tr.val=v;
tr.updateX(1,1,n);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: