这道题是典型的二维线段树的题目,题目要求查询一个区间的最小值和最大值,并修改一个点。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<set> #include<map> #include<cstdlib> using namespace std; const int INF=0x3f3f3f3f; const int maxn=1010; struct nodey { int l,r; int max,min; }; int locy[maxn],locx[maxn]; struct nodex { int l,r; nodey sty[maxn*4]; void build(int i,int _l,int _r) { sty[i].l=_l; sty[i].r=_r; sty[i].max=-INF; sty[i].min=INF; if(_l==_r) { locy[_l]=i; return; } int mid=(_l+_r)/2; build(i<<1,_l,mid); build((i<<1)|1,mid+1,_r); } int querymin(int i,int _l,int _r) { if(sty[i].l==_l&&sty[i].r==_r) return sty[i].min; int mid=(sty[i].l+sty[i].r)/2; if(_r<=mid) return querymin(i<<1,_l,_r); else if(_l>mid) return querymin((i<<1)|1,_l,_r); else return min(querymin(i<<1,_l,mid),querymin((i<<1)|1,mid+1,_r)); } int querymax(int i,int _l,int _r) { if(sty[i].l==_l&&sty[i].r==_r) return sty[i].max; int mid=(sty[i].l+sty[i].r)/2; if(_r<=mid) return querymax(i<<1,_l,_r); else if(_l>mid) return querymax((i<<1)|1,_l,_r); else return max(querymax(i<<1,_l,mid),querymax((i<<1)|1,mid+1,_r)); } }stx[maxn*4]; int n; void build(int i,int l,int r) { stx[i].l=l; stx[i].r=r; stx[i].build(1,1,n); if(l==r) { locx[l]=i; return ; } int mid=(l+r)/2; build(i<<1,l,mid); build((i<<1)|1,mid+1,r); } void modify(int x,int y,int val) { int tx=locx[x]; int ty=locy[y]; stx[tx].sty[ty].min=stx[tx].sty[ty].max=val; for(int i=tx;i;i>>=1) for(int j=ty;j;j>>=1) { if(i==tx&&j==ty) continue; if(j==ty) { stx[i].sty[j].min=min(stx[i<<1].sty[j].min,stx[(i<<1)|1].sty[j].min); stx[i].sty[j].max=max(stx[i<<1].sty[j].max,stx[(i<<1)|1].sty[j].max); } else { stx[i].sty[j].min=min(stx[i].sty[j<<1].min,stx[i].sty[(j<<1)|1].min); stx[i].sty[j].max=max(stx[i].sty[j<<1].max,stx[i].sty[(j<<1)|1].max); } } } int queryMin(int i,int x1,int x2,int y1,int y2) { if(stx[i].l==x1&&stx[i].r==x2) return stx[i].querymin(1,y1,y2); int mid=(stx[i].l+stx[i].r)/2; if(x2<=mid) return queryMin(i<<1,x1,x2,y1,y2); else if(x1>mid) return queryMin((i<<1)|1,x1,x2,y1,y2); else return min(queryMin(i<<1,x1,mid,y1,y2),queryMin((i<<1)|1,mid+1,x2,y1,y2)); } int queryMax(int i,int x1,int x2,int y1,int y2) { if(stx[i].l==x1&&stx[i].r==x2) return stx[i].querymax(1,y1,y2); int mid=(stx[i].l+stx[i].r)/2; if(x2<=mid) return queryMax(i<<1,x1,x2,y1,y2); else if(x1>mid) return queryMax((i<<1)|1,x1,x2,y1,y2); else return max(queryMax(i<<1,x1,mid,y1,y2),queryMax((i<<1)|1,mid+1,x2,y1,y2)); } int main() { int T; scanf("%d",&T); int icase=0; while(T--) { icase++; printf("Case #%d:\n",icase); scanf("%d",&n); build(1,1,n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int a; scanf("%d",&a); modify(i,j,a); } int q; int x,y,L; scanf("%d",&q); while(q--) { scanf("%d%d%d",&x,&y,&L); int x1=max(x-L/2,1); int x2=min(x+L/2,n); int y1=max(y-L/2,1); int y2=min(y+L/2,n); int Max=queryMax(1,x1,x2,y1,y2); int Min=queryMin(1,x1,x2,y1,y2); int t=(Max+Min)/2; printf("%d\n",t); modify(x,y,t); } } return 0; }
时间: 2024-08-26 00:47:46