Description
Input
接下來N行N列一共N*N個數,表示這個矩陣;
再接下來Q行每行5個數描述一個詢問:x1,y1,x2,y2,k表示找到以(x1,y1)爲左上角、以(x2,y2)爲右下角的子矩形中的第K小數。
Output
Sample Input
2 1
3 4
1 2 1 2 1
1 1 2 2 3
Sample Output
3
HINT
矩陣中數字是109以內的非負整數;
20%的數據:N<=100,Q<=1000;
40%的數據:N<=300,Q<=10000;
60%的數據:N<=400,Q<=30000;
100%的數據:N<=500,Q<=60000。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#define maxn 505
#define maxq 60005
using namespace std;
inline void read(int& x)
{ char c=getchar();x=0;int y=1;
while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
x*=y;
}
template<typename T>inline T m_min(T x,T y){return x<y?x:y;}
int n,q,sum[maxn][maxn],sz,ans[maxq],done,cnt,pre[maxq],nex[maxq],A[maxn][maxn];
struct query
{ int x1,x2,y1,y2,k;
query(int a=0,int b=0,int c=0,int d=0,int e=0):x1(a),x2(b),y1(c),y2(d),k(e){}
}Q[maxq];
struct node
{ int x,y,v;
node(int x=0,int y=0,int z=0):x(x),y(y),v(z){}
friend bool operator<(const node& a,const node& b){return a.v<b.v;}
}matrix[maxn*maxn];
int main()
{ read(n);read(q);int x,y,a,b,c;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{ read(x);
matrix[++cnt]=node(i,j,x);
}
for(int i=1;i<=q;++i)
{ read(x);read(y);read(a),read(b);read(c);
Q[i]=query(x,a,y,b,c);
pre[i]=i-1;nex[i]=i+1;
}
nex[0]=1;
sort(matrix+1,matrix+cnt+1);
register int i,j,k,lef,rig,_,__;
int now;
for(i=1;i<=n;++i)
{ lef=(i-1)*n+1;rig=lef+n-1;
for(j=lef;j<=rig;++j)
A[matrix[j].x][matrix[j].y]=1;
for(_=1;_<=n;++_)
for(__=1;__<=n;++__)
sum[_][__]=sum[_][__-1]+sum[_-1][__]-sum[_-1][__-1]+A[_][__];
for(j=nex[0];j<=q;j=nex[j])
{ now=sum[Q[j].x2][Q[j].y2]-sum[Q[j].x2][Q[j].y1-1]-sum[Q[j].x1-1][Q[j].y2]+sum[Q[j].x1-1][Q[j].y1-1];
if(now>=Q[j].k)
for(int l=rig;l>=lef;--l)
if(matrix[l].x>=Q[j].x1&&matrix[l].x<=Q[j].x2&&matrix[l].y>=Q[j].y1&&matrix[l].y<=Q[j].y2)
{ --now;
if(now<Q[j].k)
{ ans[j]=matrix[l].v;++done;
nex[pre[j]]=nex[j];pre[nex[j]]=pre[j];
break;
}
}
}
if(done==q) break;
}
for(int i=1;i<=q;++i) printf("%d\n",ans[i]);
return 0;
}