1.主席树
2.二维前缀和+二分查找
#include<bits/stdc++.h>
using namespace std;
const int Maxn = 5e5+5;
int R, C, M;
int book[Maxn], b[Maxn], root[Maxn];
int tot;
int f[205][205][1005],g[205][205][1005];
int tott[210][210][1010],num[210][210][1010],a[210][210];
int ans;
typedef struct
{
int l;
int r;
int size;
int sum;
}Node;
Node node[Maxn<<4];
int build(int l, int r)
{
int rt = ++tot;
node[rt].size = 0;
node[rt].sum = 0;
if(l<r)
{
int mid = (l+r)>>1;
node[rt].l = build(l, mid);
node[rt].r = build(mid+1, r);
}
return rt;
}
int update(int pre, int l, int r, int x)
{
int rt = ++tot;
node[rt].l = node[pre].l;
node[rt].r = node[pre].r;
node[rt].sum = node[pre].sum + b[x];
node[rt].size = node[pre].size + 1;
if(l<r)
{
int mid = (l+r)>>1;
if(x<=mid) node[rt].l = update(node[pre].l, l, mid, x);
else node[rt].r = update(node[pre].r, mid+1, r, x);
}
return rt;
}
void query(int ql, int qr, int l, int r, int h)
{
if(h<=0) return;
if(l>=r){
int tmp_size = node[qr].size - node[ql].size;
if(tmp_size*b[l]>=h)
ans += ceil(1.0*h/b[l]);
return;
}
int mid = (l+r) >> 1;
if(node[node[qr].r].sum - node[node[ql].r].sum<=h)
{
ans = ans + node[node[qr].r].size - node[node[ql].r].size;
query(node[ql].l, node[qr].l, l, mid, h-(node[node[qr].r].sum - node[node[ql].r].sum));
}
else{
query(node[ql].r, node[qr].r, mid+1, r, h);
}
}
int get_sum(int x1,int y1,int x2,int y2,int k,int f)
{
if(f==1)return tott[x2][y2][k]-tott[x2][y1-1][k]-tott[x1-1][y2][k]+tott[x1-1][y1-1][k];
else return num[x2][y2][k]-num[x2][y1-1][k]-num[x1-1][y2][k]+num[x1-1][y1-1][k];
}
void doo(){
int i,j,k,maxx=0;
for(i=1;i<=R;i++){
for(j=1;j<=C;j++){
cin >> a[i][j];maxx=max(maxx,a[i][j]);
}
}
for(k=0;k<=maxx;k++){
for(i=1;i<=R;i++){
for(j=1;j<=C;j++){
tott[i][j][k]=tott[i-1][j][k]+tott[i][j-1][k]-tott[i-1][j-1][k]+(a[i][j]>=k)*a[i][j];
num[i][j][k]=num[i-1][j][k]+num[i][j-1][k]-num[i-1][j-1][k]+(a[i][j]>=k);
}
}
}
while(M--){
int x1,y1,x2,y2,h;
cin >> x1 >> y1 >> x2 >> y2 >> h;
if(get_sum(x1,y1,x2,y2,0,1)<h) puts("Poor QLW");
else{
int l=0,r=maxx+1;ans=-1;
while(l<=r){
int mid=(l+r)>>1;
if(get_sum(x1,y1,x2,y2,mid,1)>=h){
ans=mid;l=mid+1;
}
else r=mid-1;
}
printf("%d\n",get_sum(x1,y1,x2,y2,ans,2)-(get_sum(x1,y1,x2,y2,ans,1)-h)/ans);
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> R >> C >> M;
if(R == 1)
{
for(int i = 1; i<=C; i++)
{
cin >> book[i];
b[i] = book[i];
}
sort(b+1, b+1+C);
int range = unique(b+1, b+1+C)-b-1;
root[0] = build(1, range);
for(int i = 1; i<=C; i++)
{
int tmp = lower_bound(b+1, b+1+range, book[i]) - b;
root[i] = update(root[i-1], 1, range, tmp);
}
for(int i = 1; i<=M;i++)
{
ans = 0;
int x1, x2, y1, y2, h;
cin >> x1 >> y1 >> x2 >> y2 >> h;
if(node[root[y2]].sum - node[root[y1-1]].sum>=h)
{
query(root[y1-1], root[y2], 1, range, h);
cout << ans << endl;
}
else cout << "Poor QLW" << endl;
}
}
else{
doo();
}
return 0;
}