不带修改的二维求RMQ,二维线段树。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1200; const int INF=1e9+10; int n,q; int val[maxn][maxn]; int x,y,xt,yt; struct NodeX { int Min[maxn<<2]; void up(int rt) { Min[rt]=min(Min[rt<<1],Min[rt<<1|1]); } void build(int l,int r,int rt) { if(l==r){ Min[rt]=INF; return; } int m=(l+r)>>1; build(lson); build(rson); up(rt); } void update(int p,int c,int l,int r,int rt) { if(l==r){ Min[rt]=min(Min[rt],c); return; } int m=(l+r)>>1; if(p<=m) update(p,c,lson); else update(p,c,rson); up(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return Min[rt]; int m=(l+r)>>1; int res=INF; if(L<=m) res=min(res,query(L,R,lson)); if(R>m) res=min(res,query(L,R,rson)); return res; } };NodeX tx[maxn<<2]; void build(int l,int r,int rt) { tx[rt].build(1,n,1); if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } void update(int x,int y,int c,int l,int r,int rt) { tx[rt].update(y,c,1,n,1); if(l==r) return; int m=(l+r)>>1; if(x<=m) update(x,y,c,lson); else update(x,y,c,rson); } int query(int xL,int xR,int yL,int yR,int l,int r,int rt) { if(xL<=l&&r<=xR) return tx[rt].query(yL,yR,1,n,1); int m=(l+r)>>1; int res=INF; if(xL<=m) res=min(res,query(xL,xR,yL,yR,lson)); if(xR>m) res=min(res,query(xL,xR,yL,yR,rson)); return res; } int main() { freopen("in.txt","r",stdin); int T;cin>>T; while(T--){ scanf("%d",&n); REP(i,1,n) REP(j,1,n) scanf("%d",&val[i][j]); build(1,n,1); REP(i,1,n) REP(j,1,n) update(i,j,val[i][j],1,n,1); scanf("%d",&q); while(q--){ scanf("%d%d%d%d",&x,&y,&xt,&yt); printf("%d\n",query(x,xt,y,yt,1,n,1)); } } return 0; }
我是直接把初值设为INF,然后再赋值的时候用Min[rt]=min(Min[rt],c)在每一层进行单点更新,但是这样我要怎么修改啊。。。维护个二维的RMQ连单点修改都做不到,这和咸鱼有什么区别。。。