1 3 1 2 3 4 5 6 7 8 9 5 2 2 1 3 2 3 1 1 3 1 2 3 2 2 3
Case #1: 5 6 3 4 6
思路:二维线段树,单点更新。
#include <stdio.h> #define INF 1000000001 #define min(A,B)(A<B?A:B) #define max(A,B)(A>B?A:B) int mx[3200][3200],mn[3200][3200],n,minnum,maxnum; void buildy(int x,int idx,int s,int e,bool flag)//flag为1表示第一维为叶子节点。为0表示第一维不是叶子节点 { if(s==e) { if(flag) { scanf("%d",&mn[x][idx]); mx[x][idx]=mn[x][idx]; } } else { int mid=(s+e)>>1; buildy(x,idx<<1,s,mid,flag); buildy(x,idx<<1|1,mid+1,e,flag); mx[x][idx]=max(mx[x][idx<<1],mx[x][idx<<1|1]); mn[x][idx]=min(mn[x][idx<<1],mn[x][idx<<1|1]); } if(!flag)//第一维不是叶子节点就更新第一维 { mx[x][idx]=max(mx[x<<1][idx],mx[x<<1|1][idx]); mn[x][idx]=min(mn[x<<1][idx],mn[x<<1|1][idx]); } } void build(int idx,int s,int e) { if(s!=e) { int mid=(s+e)>>1; build(idx<<1,s,mid); build(idx<<1|1,mid+1,e); buildy(idx,1,1,n,0); } else buildy(idx,1,1,n,1); } void updatey(int x,int idx,int s,int e,int pos,int val,bool flag) { if(s==e) mn[x][idx]=mx[x][idx]=val; else { int mid=(s+e)>>1; if(pos<=mid) updatey(x,idx<<1,s,mid,pos,val,flag); else updatey(x,idx<<1|1,mid+1,e,pos,val,flag); mx[x][idx]=max(mx[x][idx<<1],mx[x][idx<<1|1]); mn[x][idx]=min(mn[x][idx<<1],mn[x][idx<<1|1]); } if(!flag)//第一维不是叶子节点就更新第一维 { mx[x][idx]=max(mx[x<<1][idx],mx[x<<1|1][idx]); mn[x][idx]=min(mn[x<<1][idx],mn[x<<1|1][idx]); } } void update(int idx,int s,int e,int pos,int posy,int val) { if(s==e) updatey(idx,1,1,n,posy,val,1); else { int mid=(s+e)>>1; if(pos<=mid) update(idx<<1,s,mid,pos,posy,val); else update(idx<<1|1,mid+1,e,pos,posy,val); updatey(idx,1,1,n,posy,val,0); } } void queryy(int x,int idx,int s,int e,int l,int r) { if(s==l && e==r) { minnum=min(minnum,mn[x][idx]); maxnum=max(maxnum,mx[x][idx]); } else { int mid=(s+e)>>1; if(r<=mid) queryy(x,idx<<1,s,mid,l,r); else if(l>mid) queryy(x,idx<<1|1,mid+1,e,l,r); else { queryy(x,idx<<1,s,mid,l,mid); queryy(x,idx<<1|1,mid+1,e,mid+1,r); } } } void query(int idx,int s,int e,int l,int r,int ly,int ry) { if(s==l && e==r) queryy(idx,1,1,n,ly,ry); else { int mid=(s+e)>>1; if(r<=mid) query(idx<<1,s,mid,l,r,ly,ry); else if(l>mid) query(idx<<1|1,mid+1,e,l,r,ly,ry); else { query(idx<<1,s,mid,l,mid,ly,ry); query(idx<<1|1,mid+1,e,mid+1,r,ly,ry); } } } int main() { int T,i,q,a,b,c,l,r,ly,ry,t; scanf("%d",&T); for(i=1;i<=T;i++) { scanf("%d",&n); build(1,1,n); scanf("%d",&q); printf("Case #%d:\n",i); while(q--) { scanf("%d%d%d",&a,&b,&c); l=max(a-c/2,1); r=min(a+c/2,n); ly=max(b-c/2,1); ry=min(b+c/2,n); minnum=INF; maxnum=-INF; query(1,1,n,l,r,ly,ry); t=(minnum+maxnum)/2; printf("%d\n",t); update(1,1,n,a,b,t); } } }