您的位置:首页 > 其它

UVA-11297-Census(二维线段树RMQ,单点修改)

2017-04-11 21:06 441 查看
题目链接:UVA-11297-Census

题意是给定n*n(n<=500)大小的矩阵,询问操作是询问一个矩形内的最值,修改操作是修改某个点的值。

因此可以用二维线段树搞。

二维线段树就是线段树套线段树,x方向建立一棵线段树,其每一结点是一棵在y方向的线段树。

查询:先沿x方向查询,当该区间在查询区间内,沿y方向查询。

修改:沿x方向修改,如果这个点是x方向的叶子结点,那么在y 方向查找到叶子结点时,直接赋值即可。否则当在y方向查找到叶子结点时,要通过其在x方向的叶子结点获得在y方向叶子结点的值,详情看
push_up_2D
push_up_1D
的使用位置。

#include<bits/stdc++.h>
using namespace std;
const int maxn=507;
const int INF=1e9+7;
int n;
int Mat[maxn][maxn];
struct IntervalTree2D
{
int Max[maxn<<2][maxn<<2],Min[maxn<<2][maxn<<2];
int xl,xr,yl,yr,rt1,maxv,minv,x,y,v,leaf;
inline void push_up_2D(int rt)
{
Max[rt1][rt]=max(Max[rt1<<1][rt],Max[rt1<<1|1][rt]);
Min[rt1][rt]=min(Min[rt1<<1][rt],Min[rt1<<1|1][rt]);
}
inline void push_up_1D(int rt)
{
Max[rt1][rt]=max(Max[rt1][rt<<1],Max[rt1][rt<<1|1]);
Min[rt1][rt]=min(Min[rt1][rt<<1],Min[rt1][rt<<1|1]);
}
void build()
{
build_2D(1,1,n);
}
void build_1D(int rt,int l,int r)
{
if(l==r)
{
if(leaf) Max[rt1][rt]=Min[rt1][rt]=Mat[x][l];
else push_up_2D(rt);
return;
}
int mid=(l+r)>>1;
build_1D(rt<<1,l,mid);
build_1D(rt<<1|1,mid+1,r);
push_up_1D(rt);
}
void build_2D(int rt,int l,int r)
{
if(l==r)
{
leaf=true;
x=l;
rt1=rt;
build_1D(1,1,n);
return;
}
int mid=(l+r)>>1;
build_2D(rt<<1,l,mid);
build_2D(rt<<1|1,mid+1,r);
leaf=false;rt1=rt;
build_1D(1,1,n);
}
void query(int _xl,int _xr,int _yl,int _yr)
{
xl=_xl;xr=_xr;yl=_yl;yr=_yr;
minv=INF;maxv=-INF;
query_2D(1,1,n);
}
void query_2D(int rt,int l,int r)
{
if(r<=xr&&l>=xl)
{
rt1=rt;
query_1D(1,1,n);
return;
}
int mid=(l+r)>>1;
if(xl<=mid) query_2D(rt<<1,l,mid);
if(xr>mid) query_2D(rt<<1|1,mid+1,r);
}
void query_1D(int rt,int l,int r)
{
if(l>=yl&&r<=yr)
{
maxv=max(maxv,Max[rt1][rt]);
minv=min(minv,Min[rt1][rt]);
return;
}
int mid=(l+r)>>1;
if(yl<=mid) query_1D(rt<<1,l,mid);
if(yr>mid) query_1D(rt<<1|1,mid+1,r);
}
void modify(int _x,int _y,int _v)
{
x=_x;y=_y;v=_v;
modify_2D(1,1,n);
}
void modify_1D(int rt,int l,int r)
{
if(l==r)
{
if(leaf) Max[rt1][rt]=Min[rt1][rt]=v;
else push_up_2D(rt);
return;
}
int mid=(l+r)>>1;
if(y<=mid) modify_1D(rt<<1,l,mid);
if(y>mid) modify_1D(rt<<1|1,mid+1,r);
push_up_1D(rt);
}
void modify_2D(int rt,int l,int r)
{
if(l==r)
{
rt1=rt;
leaf=true;
modify_1D(1,1,n);
return;
}
int mid=(l+r)>>1;
if(x<=mid) modify_2D(rt<<1,l,mid);
if(x>mid) modify_2D(rt<<1|1,mid+1,r);
rt1=rt;
leaf=false;
modify_1D(1,1,n);
}
}tree;
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&Mat[i][j]);
tree.build();
int q,x1,y1,x2,y2,x,y,v;
scanf("%d",&q);
char op[10];
while(q--)
{
scanf("%s",op);
if(op[0]=='q')
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
tree.query(min(x1,x2),max(x1,x2),min(y1,y2),max(y1,y2));
printf("%d %d\n",tree.maxv,tree.minv);
}
else
{
scanf("%d%d%d",&x,&y,&v);
tree.modify(x,y,v);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: