C3H5ClO
2020-09-14 11:23:44
发一个
首先,这道题空间没法搞树状数组套线段树之类的,只能整体二分。
在整体二分中的某一次分治时,假设值域为
上代码:
#include<bits/stdc++.h>
using namespace std;
const int N=505,M=60005;
int n,q,a[N][N],ans[M],x,y,xx,yy,z;
int aa[N*N],lenaa,dx[M],o2p[M],o2p1[M],o2p2[M];
struct node{int v,x,y;}o[N*N];
bool operator <(node a,node b){return a.v<b.v;}
struct node2{int x1,y1,x2,y2,k,id;}o2[M];
struct node3{int x,y,id;}o3[N*N*2];
bool operator <(node3 a,node3 b){return a.x!=b.x?a.x<b.x:!a.id&&b.id;}
int sz[N*N];
void ddxg(int x,int y){for(;x<=lenaa;x+=x&-x)sz[x]+=y;}
int qjcx(int x){int y=0; for(;x;x-=x&-x)y+=sz[x]; return y;}
void getans(int l,int r,int o2l,int o2r)
{
if(l==r){for(int i=o2l;i<=o2r;i++)ans[o2[o2p[i]].id]=aa[o[l].v]; return;}
int mid=l+r>>1,len1=0,len2=0,len3=0;
for(int i=l;i<=mid;i++)o3[++len3]={o[i].x,o[i].y,0};
for(int i=o2l;i<=o2r;i++)
{
x=o2[o2p[i]].x1; y=o2[o2p[i]].y1; xx=o2[o2p[i]].x2; yy=o2[o2p[i]].y2;
o3[++len3]={xx,yy,i}; o3[++len3]={x-1,y-1,i};
o3[++len3]={xx,y-1,-i}; o3[++len3]={x-1,yy,-i};
}
sort(o3+1,o3+len3+1);
for(int i=1;i<=len3;i++)
if(!o3[i].id)ddxg(o3[i].y,1);
else if(o3[i].id>0)dx[o3[i].id]+=qjcx(o3[i].y);
else dx[-o3[i].id]-=qjcx(o3[i].y);
for(int i=o2l;i<=o2r;i++)
if(o2[o2p[i]].k<=dx[i])o2p1[++len1]=o2p[i];
else o2[o2p[i]].k-=dx[i],o2p2[++len2]=o2p[i];
for(int i=1;i<=len1;i++)o2p[o2l+i-1]=o2p1[i];
for(int i=1;i<=len2;i++)o2p[o2l+len1+i-1]=o2p2[i];
fill(dx+o2l,dx+o2r+1,0);
for(int i=l;i<=mid;i++)ddxg(o[i].y,-1);
if(len1)getans(l,mid,o2l,o2l+len1-1);
if(len2)getans(mid+1,r,o2l+len1,o2r);
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",a[i]+j),aa[++lenaa]=a[i][j];
sort(aa+1,aa+lenaa+1);
lenaa=unique(aa+1,aa+lenaa+1)-aa-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=lower_bound(aa+1,aa+lenaa+1,a[i][j])-aa,o[i*n-n+j]={a[i][j],i,j};
sort(o+1,o+n*n+1);
for(int i=1;i<=q;i++)scanf("%d%d%d%d%d",&x,&y,&xx,&yy,&z),o2[i]={x,y,xx,yy,z,i},o2p[i]=i;
getans(1,n*n,1,q);
for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
}