這道題還是整體二分。。 在二維樹狀數組外面套一個二分
但對於這道題來說,整體二分的複雜度是 Q*log(Q)^3 不如分塊優(Q*sqrt(Q))
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <functional>
#define INF 1000000000
#define MAXN 350000
#define lowbit(x) ((x)&(-(x)))
using namespace std;
struct node
{
int x1,y1,x2,y2,s,k,cur,tp;
}q[MAXN],q1[MAXN],q2[MAXN];
int tmp[MAXN],ans[MAXN];
int c[600][600];
int n,m,tot;
void modify(const int &x,const int &y,const int &d)
{
for (int i=x;i<=n;i+=lowbit(i))
for (int j=y;j<=n;j+=lowbit(j))
c[i][j]+=d;
}
int query(const int &x,const int &y)
{
int res=0;
for (int i=x;i>0;i-=lowbit(i))
for (int j=y;j>0;j-=lowbit(j))
res+=c[i][j];
return res;
}
void solve(int head,int tail,int L,int R)
{
if (head>tail) return;
if (L==R)
{
for (int i=head;i<=tail;++i)
if (q[i].tp==2) ans[q[i].s]=L;
return;
}
int mid=(L+R)/2;
for (int i=head;i<=tail;++i)
{
if (q[i].tp==1&&q[i].k<=mid) modify(q[i].x1,q[i].y1,1);
else if (q[i].tp==2) tmp[i]=query(q[i].x2,q[i].y2)-query(q[i].x1-1,q[i].y2)-query(q[i].x2,q[i].y1-1)+query(q[i].x1-1,q[i].y1-1);
}
for (int i=head;i<=tail;++i)
if (q[i].tp==1&&q[i].k<=mid) modify(q[i].x1,q[i].y1,-1);
int l1=0,l2=0;
for (int i=head;i<=tail;++i)
{
if (q[i].tp==2)
{
if (q[i].cur+tmp[i]>q[i].k-1)
q1[++l1]=q[i];
else
{
q[i].cur+=tmp[i];
q2[++l2]=q[i];
}
}
else
{
if (q[i].k<=mid) q1[++l1]=q[i];
else q2[++l2]=q[i];
}
}
for (int i=1;i<=l1;++i) q[head+i-1]=q1[i];
for (int i=1;i<=l2;++i) q[head+l1+i-1]=q2[i];
solve(head,head+l1-1,L,mid);
solve(head+l1,tail,mid+1,R);
}
int getint()
{
char c;
int res=0;
while (isspace(c=getchar())) ;
res=c-48;
while (isdigit(c=getchar())) res=res*10+c-48;
return res;
}
int main()
{
cin>>n>>m;
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
{
int x;
x=getint();
q[++tot].x1=i;q[tot].y1=j;
q[tot].k=x;q[tot].tp=1;
}
for (int i=1;i<=m;++i)
{
++tot;
q[tot].x1=getint(),q[tot].y1=getint(),q[tot].x2=getint(),q[tot].y2=getint(),q[tot].k=getint();
q[tot].tp=2; q[tot].s=i;
}
solve(1,tot,0,INF);
for (int i=1;i<=m;++i)
printf("%d\n",ans[i]);
}