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方向叶子结点的值,详情看
题意是给定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; }
相关文章推荐
- UVa 11297 Census(二维线段树+单点更新)
- UVa 11297 Census (二维线段树)
- UVA 11297 Census(二维线段树)
- UVA:11297-Census(二维线段树)
- Uva 11297 Census 二维线段树
- Uva 11297 Census,二维线段树,板子
- UVA - 12299 RMQ with Shifts (线段树:单点修改,区间查询)
- UVa 11297 Census 二维线段树模板
- UVa 12299 RMQ with shifts(线段树单点修改 区间查询)
- UVA11297--Census(二维线段树)
- 树套树:二维线段树初步:hdu1823——Luck and Love(单点修改,区间查询)
- POJ 2155 二维线段树 经典的记录所有修改再统一遍历 单点查询
- UVa 12299 线段树 单点更新 RMQ with Shifts
- 文章标题 UVA 12299 : RMQ with Shifts(线段树+点修改)
- 二维线段树区间修改(add,set)uva11992
- UVA12299 RMQ with Shifts 线段树查询 单点更新
- POJ 2155 Matrix 二维线段树 区间修改 单点查询
- UVA-11297 Census(线段树套线段树)
- uva 12299 - RMQ with Shifts--- 线段树单点更新
- hdu 4819 二维线段树,单点修改区间查询