1 #include<cstdio> 2 #include<iostream> 3 #define N 201 4 #define M 500008 5 using namespace std; 6 int cnt,r,c,m,ls[20*M],rs[20*M],root[M],ans,sum[20*M],sum1[20*M],shu,num[1008][N][N],num1[1008][N][N]; 7 void jia(int l,int r,int x,int &y,int v) 8 { 9 y=++cnt; 10 sum[y]=sum[x]+v; 11 sum1[y]=sum1[x]+1; 12 if(l==r) 13 return; 14 ls[y]=ls[x]; 15 rs[y]=rs[x]; 16 int mid=(l+r)>>1; 17 if(v<=mid) 18 jia(l,mid,ls[x],ls[y],v); 19 else 20 jia(mid+1,r,rs[x],rs[y],v); 21 return; 22 } 23 int xun(int a1,int a2,int l,int r,int v) 24 { 25 if(!a1) 26 return 0; 27 if(l>=v) 28 { 29 shu-=sum[a1]-sum[a2]; 30 return sum1[a1]-sum1[a2]; 31 } 32 int s=0,mid=(l+r)>>1; 33 if(mid>=v) 34 s+=xun(ls[a1],ls[a2],l,mid,v); 35 s+=xun(rs[a1],rs[a2],mid+1,r,v); 36 return s; 37 } 38 void solve1() 39 { 40 for(int i=1;i<=c;i++) 41 { 42 int a1; 43 scanf("%d",&a1); 44 jia(1,1000,root[i-1],root[i],a1); 45 } 46 for(int i=1;i<=m;i++) 47 { 48 int x0,y0,x1,y1,v; 49 scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&v); 50 int l=0,r=1000,mid=(l+r)>>1,b1,md,md1; 51 ans=0; 52 for(;l<=r;) 53 { 54 shu=v; 55 b1=xun(root[y1],root[y0-1],1,1000,mid); 56 if(shu<=0) 57 { 58 md1=v-shu; 59 md=mid; 60 ans=b1; 61 l=mid+1; 62 } 63 else 64 r=mid-1; 65 mid=(l+r)>>1; 66 } 67 if(!ans) 68 printf("Poor QLW\n"); 69 else 70 { 71 int a1; 72 r=xun(root[y1],root[y0-1],1,1000,md+1); 73 r=ans-r; 74 l=0; 75 mid=(l+r)>>1; 76 for(;l<=r;) 77 { 78 if(md1-mid*md>=v) 79 { 80 a1=ans-mid; 81 l=mid+1; 82 } 83 else 84 r=mid-1; 85 mid=(l+r)>>1; 86 } 87 printf("%d\n",a1); 88 } 89 } 90 return; 91 } 92 void solve2() 93 { 94 for(int i=1;i<=r;i++) 95 for(int j=1;j<=c;j++) 96 { 97 int a1; 98 scanf("%d",&a1); 99 for(int k=0;k<=1000;k++) 100 { 101 num[k][i][j]=(num[k][i][j-1]+num[k][i-1][j]-num[k][i-1][j-1]); 102 num1[k][i][j]=(num1[k][i][j-1]+num1[k][i-1][j]-num1[k][i-1][j-1]); 103 if(a1>=k) 104 { 105 num[k][i][j]+=a1; 106 num1[k][i][j]++; 107 } 108 } 109 } 110 for(int i=1;i<=m;i++) 111 { 112 int x0,y0,x1,y1,v; 113 scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&v); 114 int l=0,r=1000,mid=(l+r)>>1,tm=0,tm1=0,tm2=0; 115 for(;l<=r;) 116 { 117 if(num[mid][x1][y1]-num[mid][x1][y0-1]-num[mid][x0-1][y1]+num[mid][x0-1][y0-1]>=v) 118 { 119 tm=num1[mid][x1][y1]-num1[mid][x1][y0-1]-num1[mid][x0-1][y1]+num1[mid][x0-1][y0-1]; 120 tm1=mid; 121 l=mid+1; 122 } 123 else 124 r=mid-1; 125 mid=(l+r)>>1; 126 } 127 if(!tm) 128 printf("Poor QLW\n"); 129 else 130 { 131 tm2=num[tm1][x1][y1]-num[tm1][x1][y0-1]-num[tm1][x0-1][y1]+num[tm1][x0-1][y0-1]; 132 l=0,r=num1[tm1+1][x1][y1]-num1[tm1+1][x1][y0-1]-num1[tm1+1][x0-1][y1]+num1[tm1+1][x0-1][y0-1]; 133 r=tm-r; 134 mid=(l+r)>>1; 135 for(;l<=r;) 136 { 137 if(tm2-mid*tm1>=v) 138 { 139 ans=tm-mid; 140 l=mid+1; 141 } 142 else 143 r=mid-1; 144 mid=(l+r)>>1; 145 } 146 printf("%d\n",ans); 147 } 148 } 149 return; 150 } 151 int main() 152 { 153 scanf("%d%d%d",&r,&c,&m); 154 if(r==1) 155 solve1(); 156 else 157 solve2(); 158 return 0; 159 }
两种情况 对于R,C<=200,用前缀和暴力二分,对于另外的数据,在主席树上二分。