整体二分

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\n",ans[i]);
  }

 

posted @ 2016-12-26 10:43  z1j1n1  阅读(155)  评论(0编辑  收藏  举报