首先和矩阵乘法无关
感觉好久没有学习新的东西了,整体二分?和我的二分答案貌似差别挺大的
这基本是一道整体二分的模板题了,将整个矩阵用序列保存然后按权值排序,然后用神奇的整体二分处理询问
所以说今天又只是打了个板子??QAQ
#include<cstdio>
#include<algorithm>
#define N 505
#define M 60005
#define RG register
using namespace std;
inline int read()
{
int a=0,f=1;static char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}
return a*f;
}
struct node{int x,y,v;}a[N*N];
struct question{int x1,y1,x2,y2,k,id;}q[M],xl1[M],xl2[M];
int n,m,cnt=0;
int ans[M],t[N][N];
int cmp(node x,node y){return x.v<y.v;}
inline int lowbit(int x){return x&-x;}
void change(int x,int y,int c)
{
RG int i,j;
for(i=x;i<=n;i+=lowbit(i))
for(j=y;j<=n;j+=lowbit(j))
t[i][j]+=c;
}
int ask(int x,int y)
{
RG int i,j,res=0;
for(i=x;i;i-=lowbit(i))
for(j=y;j;j-=lowbit(j))
res+=t[i][j];
return res;
}
int query(question Q)
{
return ask(Q.x2,Q.y2)-ask(Q.x1-1,Q.y2)-ask(Q.x2,Q.y1-1)+ask(Q.x1-1,Q.y1-1);
}
void solve(int l,int r,int L,int R)
{
RG int i;
if(L>R) return;
if(l==r)
{
for(i=L;i<=R;++i)
ans[q[i].id]=a[l].v;
return;
}
int mid=(l+r)>>1;
for(i=l;i<=mid;++i)
change(a[i].x,a[i].y,1);
int ln=0,rn=0;
for(i=L;i<=R;++i)
{
int mark=query(q[i]);
if(mark>=q[i].k) xl1[++ln]=q[i];
else q[i].k-=mark,xl2[++rn]=q[i];
}
for(i=l;i<=mid;++i)
change(a[i].x,a[i].y,-1);
int t=L;
for(i=1;i<=ln;++i) q[t++]=xl1[i];
for(i=1;i<=rn;++i) q[t++]=xl2[i];
solve(l,mid,L,L+ln-1);
solve(mid+1,r,L+ln,R);
}
int main()
{
n=read(),m=read();
RG int i,j;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
{
++cnt;a[cnt].x=i,a[cnt].y=j;
a[cnt].v=read();
}
sort(a+1,a+cnt+1,cmp);
for(i=1;i<=m;++i)
{
q[i].x1=read(),q[i].y1=read();
q[i].x2=read(),q[i].y2=read();
q[i].k=read();q[i].id=i;
}
solve(1,cnt,1,m);
for(i=1;i<=m;++i)
printf("%d\n",ans[i]);
return 0;
}