【SDOI2010】 粟粟的书架

传送门

代码

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<math.h>
  6 #define maxn 500005
  7 using namespace std;
  8 int R,C,M;
  9 int cont[1005];
 10 int he[205][205][1005],nu[205][205][1005],a[205][205];
 11 long long hh[maxn],sum[maxn*11];
 12 int lson[maxn*11],rson[maxn*11],cnt=1,root[maxn],num[maxn*11];
 13 inline void ins(int &ID,int IDl,int nl,int nr,long long v){
 14     if(!ID)ID=++cnt;
 15     if(nl==nr){
 16         num[ID]=num[IDl]+1,sum[ID]=v+sum[IDl];  //注意!!!!
 17         return;
 18     }
 19     int m=(nl+nr)>>1;
 20     if(m>=v){
 21         rson[ID]=rson[IDl];
 22         ins(lson[ID],lson[IDl],nl,m,v);
 23     }
 24     else {
 25         lson[ID]=lson[IDl];
 26         ins(rson[ID],rson[IDl],m+1,nr,v);
 27     }
 28     sum[ID]=sum[lson[ID]]+sum[rson[ID]];
 29     num[ID]=num[lson[ID]]+num[rson[ID]];
 30 }
 31 inline int query(int ID,int IDl,int nl,int nr,long long v){
 32     if(nl==nr)return ceil((double)v/nl);
 33     int ans,m=(nl+nr)>>1;
 34     if(sum[rson[ID]]-sum[rson[IDl]]<=v)return ans=num[rson[ID]]-num[rson[IDl]]+query(lson[ID],lson[IDl],nl,m,v-(sum[rson[ID]]-sum[rson[IDl]]));
 35     else return ans=query(rson[ID],rson[IDl],m+1,nr,v);
 36 }
 37 inline long long calc(int k,int x1,int y1,int x2,int y2){
 38     return he[x2][y2][k]-he[x1-1][y2][k]-he[x2][y1-1][k]+he[x1-1][y1-1][k];
 39 }
 40 inline int get_ans(int k,int x1,int y1,int x2,int y2){
 41     return nu[x2][y2][k]-nu[x1-1][y2][k]-nu[x2][y1-1][k]+nu[x1-1][y1-1][k];
 42 }
 43 inline void solve(){
 44     for(register int i=1;i<=R;i++){
 45         for(register int j=1;j<=C;j++){
 46             scanf("%lld",&a[i][j]);
 47             cont[a[i][j]]++;
 48         }
 49     }
 50     for(register int k=1;k<=1000;k++){
 51         for(register int i=1;i<=R;i++){
 52             for(register int j=1;j<=C;j++){
 53                 he[i][j][k]=he[i-1][j][k]+he[i][j-1][k]-he[i-1][j-1][k];
 54                 nu[i][j][k]=nu[i-1][j][k]+nu[i][j-1][k]-nu[i-1][j-1][k];
 55                 if(a[i][j]>=k)he[i][j][k]+=a[i][j],nu[i][j][k]++;
 56             }
 57         }
 58     }
 59     register int x1,x2,y1,y2;
 60     register long long h;
 61     while(M--){
 62         scanf("%d%d%d%d%lld",&x1,&y1,&x2,&y2,&h);
 63         if(calc(1,x1,y1,x2,y2)<h){
 64             printf("Poor QLW\n");
 65             continue;
 66         }
 67         int l=1,r=1000;
 68         while(l<=r){
 69             int m=(l+r)>>1;
 70             if(calc(m,x1,y1,x2,y2)>=h)l=m+1;
 71             else r=m-1;
 72         }
 73         int final=(l+r)>>1;
 74         int ans=get_ans(final,x1,y1,x2,y2);
 75         int fsum=calc(final,x1,y1,x2,y2);
 76         int jian=cont[final];
 77         while(jian&&fsum-final>=h){
 78             jian--,fsum-=final,ans--;
 79         }
 80         printf("%d\n",ans);
 81     }
 82 }
 83 int main(){
 84     scanf("%d%d%d",&R,&C,&M);
 85     if(R!=1){
 86         solve();
 87         return 0;
 88     }
 89     register int x1,x2,y1,y2;
 90     register long long h,maxh=0;
 91     for(register int i=1;i<=C;i++){
 92         scanf("%lld",&hh[i]);
 93         maxh=max(maxh,hh[i]);
 94     }
 95     root[0]=1;
 96     for(register int i=1;i<=C;i++){
 97         ins(root[i],root[i-1],1,maxh,hh[i]);
 98     }
 99     for(register int i=1;i<=M;i++){
100         scanf("%d%d%d%d%lld",&x1,&y1,&x2,&y2,&h);
101         if(sum[root[y2]]-sum[root[y1-1]]<h){
102             printf("Poor QLW\n");
103             continue;
104         }
105         else printf("%d\n",query(root[y2],root[y1-1],1,maxh,h));
106     }
107 }

猜你喜欢

转载自www.cnblogs.com/Fang-Hao/p/9027119.html