很好的一道题,令人大开眼界。
Code:
#include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 1000000 #define N 600 using namespace std; int n,Q,idx,q[maxn],tl[maxn],tr[maxn],answer[maxn],cur[maxn]; struct MAT{ int x,y,w; }mat[maxn]; int cmp(MAT a,MAT b){ return a.w<b.w;} struct Query{ int a,b,c,d,k; }ask[maxn]; struct BIT{ int C[N][N]; int lowbit(int x){ return x&(-x);} void add(int x,int y,int k) { for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=n;j+=lowbit(j)) C[i][j]+=k; } int query(int x,int y) { int ans=0; for(int i=x;i>0;i-=lowbit(i)) for(int j=y;j>0;j-=lowbit(j)) ans+=C[i][j]; return ans; } int ask(Query a) { return query(a.c,a.d)-query(a.c,a.b-1)-query(a.a-1,a.d)+query(a.a-1,a.b-1); } }tree; void solve(int x,int y,int l,int r){ if(x>y||l>r) return; if(l==r){ for(int i=x;i<=y;++i) answer[q[i]]=mat[l].w; return; } int mid=(l+r)>>1; for(int i=l;i<=mid;++i) tree.add(mat[i].x,mat[i].y,1); int left=0,right=0,s,u; for(int i=x;i<=y;++i){ u=q[i]; s=cur[u]+tree.ask(ask[u]); if(s>=ask[u].k) tl[++left]=u; else tr[++right]=u,cur[u]=s; } int qcnt=x-1; for(int i=1;i<=left;++i) q[++qcnt]=tl[i]; for(int i=1;i<=right;++i) q[++qcnt]=tr[i]; for(int i=l;i<=mid;++i) tree.add(mat[i].x,mat[i].y,-1); solve(x,x+left-1,l,mid),solve(x+left,y,mid+1,r); } int main(){ //setIO("input"); scanf("%d%d",&n,&Q); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j){ mat[++idx].x=i,mat[idx].y=j; scanf("%d",&mat[idx].w); } sort(mat+1,mat+1+idx,cmp); for(int i=1;i<=Q;++i) scanf("%d%d%d%d%d",&ask[i].a,&ask[i].b,&ask[i].c,&ask[i].d,&ask[i].k),q[i]=i; solve(1,Q,1,idx); for(int i=1;i<=Q;++i) printf("%d ",answer[i]); return 0; }