# [BZOJ1926][SDOI2010]粟粟的书架

BZOJ
Luogu
Description

Input

Output

5 5 7
14 15 9 26 53
58 9 7 9 32
38 46 26 43 38
32 7 9 50 28
8 41 9 7 17
1 2 5 3 139
3 1 5 5 399
3 3 4 5 91
4 1 4 1 33
1 3 5 4 185
3 3 4 3 23
3 1 3 3 108


6
15
2
Poor QLW
9
1
3


1 10 7
14 15 9 26 53 58 9 7 9 32
1 2 1 9 170
1 2 1 9 171
1 5 1 7 115
1 1 1 10 228
1 4 1 4 45704571
1 1 1 1 1
1 7 1 8 16


6
7
3
10
Poor QLW
1
2


HINT

# sol

$num_{i,j,k}$表示前$i$行前$j$列内页数大于等于$k$的书的本数。
$sum_{i,j,k}$表示前$i$行前$j$列内页数大于等于$k$的书的页数和。

## code

#include<cstdio>
#include<algorithm>
using namespace std;
int R,C,M,x1,y1,x2,y2,H;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}

int val[202][202],num[202][202][1002],sum[202][202][1002],l,r;
int Sum(int k){return sum[x2][y2][k]-sum[x1-1][y2][k]-sum[x2][y1-1][k]+sum[x1-1][y1-1][k];}
int Num(int k){return num[x2][y2][k]-num[x1-1][y2][k]-num[x2][y1-1][k]+num[x1-1][y1-1][k];}
void work1()
{
for (int i=1;i<=R;i++)
for (int j=1;j<=C;j++)
val[i][j]=gi();
for (int i=1;i<=R;i++)
for (int j=1;j<=C;j++)
for (int k=1;k<=1000;k++)
{
num[i][j][k]=num[i-1][j][k]+num[i][j-1][k]-num[i-1][j-1][k]+(val[i][j]>=k?1:0);
sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]-sum[i-1][j-1][k]+(val[i][j]>=k?val[i][j]:0);
}
while (M--)
{
x1=gi();y1=gi();x2=gi();y2=gi();H=gi();
l=0;r=1000;
while (l<r)
{
int mid=l+r+1>>1;
if (Sum(mid)>=H) l=mid;
else r=mid-1;
}
if (!l) puts("Poor QLW");
else printf("%d\n",Num(l)-(Sum(l)-H)/l);
}
}
struct president_tree{int ls,rs,num,sum;}t[10000000];
int rt[500005],tot;
void update(int &x,int l,int r,int pos)
{
t[++tot]=t[x];
t[x=tot].num++;t[x].sum+=pos;
if (l==r) return;
int mid=l+r>>1;
if (pos<=mid) update(t[x].ls,l,mid,pos);
else update(t[x].rs,mid+1,r,pos);
}
int query(int A,int B,int l,int r)
{
if (l==r) return (H+l-1)/l;
int k=t[t[A].rs].sum-t[t[B].rs].sum,mid=l+r>>1;
if (k>=H) return query(t[A].rs,t[B].rs,mid+1,r);
else {H-=k;return t[t[A].rs].num-t[t[B].rs].num+query(t[A].ls,t[B].ls,l,mid);}
}
void work2()
{
for (int i=1;i<=C;i++)
{
rt[i]=rt[i-1];
int x=gi();update(rt[i],1,1000,x);
}
while (M--)
{
gi();y1=gi();gi();y2=gi();H=gi();
if (t[rt[y2]].sum-t[rt[y1-1]].sum<H) puts("Poor QLW");
else printf("%d\n",query(rt[y2],rt[y1-1],1,1000));
}
}
int main()
{
R=gi();C=gi();M=gi();
if (R>1) work1();
else work2();
return 0;
}


posted @ 2018-01-02 22:14  租酥雨  阅读(112)  评论(0编辑  收藏