题面:
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#define ll long long
#define llu unsigned ll
#define pr make_pair
#define pb push_back
#define y1 yy
using namespace std;
const int maxn=500100;
const int maxk=1005;
int sum[210][210][1010],num[210][210][1010];
int a[210][210];
int root[maxn];
struct node
{
int lc,rc;
int sum,si;
}t[maxn*22];
int r,c,m,cnt=0;
int x1,y1,x2,y2,h;
void pushup(int p)
{
t[p].si=t[t[p].lc].si+t[t[p].rc].si;
t[p].sum=t[t[p].lc].sum+t[t[p].rc].sum;
}
int _insert(int now,int l,int r,int pos)
{
int p=++cnt;
t[p]=t[now];
if(l==r)
{
t[p].si++;
t[p].sum+=pos;
return p;
}
int mid=(l+r)>>1;
if(pos<=mid) t[p].lc=_insert(t[now].lc,l,mid,pos);
else t[p].rc=_insert(t[now].rc,mid+1,r,pos);
pushup(p);
return p;
}
int ask(int pl,int pr,int l,int r,int k)
{
if(l==r)
{
//需要多少本书
if(t[pr].sum-t[pl].sum>=k)
return k/l+(k%l!=0);
}
int mid=(l+r)>>1;
int ans=t[t[pr].rc].sum-t[t[pl].rc].sum;
if(ans<k) return t[t[pr].rc].si-t[t[pl].rc].si+ask(t[pl].lc,t[pr].lc,l,mid,k-ans);
else return ask(t[pl].rc,t[pr].rc,mid+1,r,k);
}
//r==1时是一条链,转化为贪心取厚的书。
void do_it1(void)
{
int x;
for(int i=1;i<=c;i++)
scanf("%d",&x),root[i]=_insert(root[i-1],1,maxk,x);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
if(t[root[y2]].sum-t[root[y1-1]].sum<h)
printf("Poor QLW\n");
else
printf("%d\n",ask(root[y1-1],root[y2],1,maxk,h));
}
}
int get_sum(int x1,int y1,int x2,int y2,int k)
{
return sum[x2][y2][k]-sum[x2][y1-1][k]-sum[x1-1][y2][k]+sum[x1-1][y1-1][k];
}
int get_num(int x1,int y1,int x2,int y2,int k)
{
return num[x2][y2][k]-num[x2][y1-1][k]-num[x1-1][y2][k]+num[x1-1][y1-1][k];
}
void do_it2(void)
{
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
scanf("%d",&a[i][j]);
for(int k=0;k<=maxk;k++)
{
sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]-sum[i-1][j-1][k]+(a[i][j]>=k?a[i][j]:0);
num[i][j][k]=num[i-1][j][k]+num[i][j-1][k]-num[i-1][j-1][k]+(a[i][j]>=k);
}
}
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
int l=0,r=maxk;
int mid,ans=-1;
while(l<=r)
{
mid=(l+r)>>1;
if(get_sum(x1,y1,x2,y2,mid)>=h) ans=mid,l=mid+1;
else r=mid-1;
}
//某一高度(ans)的书本可能不需要全用
if(ans==-1) printf("Poor QLW\n");
else printf("%d\n",get_num(x1,y1,x2,y2,ans)-(get_sum(x1,y1,x2,y2,ans)-h)/ans);
}
}
int main(void)
{
scanf("%d%d%d",&r,&c,&m);
if(r==1) do_it1();
else do_it2();
return 0;
}