BZOJ2738
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int n,tr[501][501],ans[60001],now,q,cnt; struct data{ int x,y,num; }a[250001]; struct quer{ int x1,y1,x2,y2,k,po; }que[60001],tmp[60001]; int mycomp(const data&a,const data&b){ return(a.num<b.num); } int lowbit(int x){ return(x&(-x)); } void edi(int x,int y,int num){ for (int i=x;i<=n;i+=lowbit(i)) for (int j=y;j<=n;j+=lowbit(j)) tr[i][j]+=num; } int query(int x,int y){ int ret=0; for (int i=x;i;i-=lowbit(i)) for (int j=y;j;j-=lowbit(j)) ret+=tr[i][j]; return(ret); } void work(int l,int r,int ql,int qr){ if (l==r){ for (int i=ql;i<=qr;i++) ans[que[i].po]=l; return; } int mid=(l+r)>>1; while (now<n*n&&a[now+1].num<=mid){ now++; edi(a[now].x,a[now].y,1); } while (now&&a[now].num>mid){ edi(a[now].x,a[now].y,-1); now--; } int po1=ql-1,po2=qr+1; for (int i=ql;i<=qr;i++){ int num=query(que[i].x2,que[i].y2)-query(que[i].x1-1,que[i].y2)-query(que[i].x2,que[i].y1-1)+query(que[i].x1-1,que[i].y1-1); if (num>=que[i].k) tmp[++po1]=que[i];else tmp[--po2]=que[i]; } for (int i=ql;i<=qr;i++) que[i]=tmp[i]; if (ql<=po1) work(l,mid,ql,po1); if (po2<=qr) work(mid+1,r,po2,qr); } int main(){ scanf("%d%d",&n,&q); int maxnum=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++){ scanf("%d",&a[++cnt].num); a[cnt].x=i;a[cnt].y=j; maxnum=max(maxnum,a[cnt].num); } sort(a+1,a+cnt+1,mycomp); for (int i=1;i<=q;i++){ scanf("%d%d%d%d%d",&que[i].x1,&que[i].y1,&que[i].x2,&que[i].y2,&que[i].k); que[i].po=i; } now=0; work(0,maxnum,1,q); for (int i=1;i<=q;i++) printf("%d ",ans[i]); }