建议添加上 莫队 和 分块 的标签,这题的sub2不一定要用主席树做。
下面是sub2用莫队和分块的代码:
#include<bits/stdc++.h>
using namespace std;
const int len=sqrt(1000);
int n,m,q,fs[205][205][1005],f[205][205][1005],ans[20005],lt=1,rt,block;
struct node{int l,r,h,id;}qs[20005];int a[500005],t[2005],tot[45],sum[45];
inline bool cmp(node x,node y){return (x.l-1)/block==(y.l-1)/block?x.r<y.r:(x.l-1)/block<(y.l-1)/block;}
inline int id(int x){return (x-1)/len+1;}
inline void add(int x){t[x]++,tot[id(x)]++,sum[id(x)]+=x;return;}
inline void del(int x){t[x]--,tot[id(x)]--,sum[id(x)]-=x;return;}
inline int query(int h,int id){
int pos=-1,res=0,tmp=0;
for(int i=35;i>=1;i--){
if(tmp+sum[i]>=h){
pos=i;break;
}res+=tot[i],tmp+=sum[i];
}if(pos==-1)return -1;
for(int i=pos*len;i>=(pos-1)*len+1;i--){
if(tmp+t[i]*i>=h){
return res+(h-tmp+i-1)/i;
}res+=t[i],tmp+=t[i]*i;
}
}
inline int read(){
register int x=0,t=0;
static char ch=getchar();
while(!isdigit(ch)) t|=(ch=='-'),ch=getchar();
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return t?-x:x;
}
signed main(){
n=read(),m=read(),q=read();
if(n==1){n=m,block=sqrt(n)*__lg(n);
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=q;i++){
int l,r,h;l=read(),l=read(),r=read(),r=read(),h=read();
qs[i]={l,r,h,i};
}sort(qs+1,qs+1+q,cmp);
for(int i=1;i<=q;i++){
while(lt>qs[i].l)add(a[--lt]);while(rt<qs[i].r)add(a[++rt]);
while(lt<qs[i].l)del(a[lt++]);while(rt>qs[i].r)del(a[rt--]);
ans[qs[i].id]=query(qs[i].h,qs[i].id);
}
for(int i=1;i<=q;i++){
if(ans[i]==-1)cout<<"Poor QLW\n";
else cout<<ans[i]<<'\n';
}
}else{
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<=1000;k++)fs[i][j][k]=fs[i-1][j][k]+fs[i][j-1][k]-fs[i-1][j-1][k];
fs[i][j][read()]++;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=1000;k>=1;k--){
f[i][j][k]=f[i][j][k+1]+fs[i][j][k]*k,fs[i][j][k]+=fs[i][j][k+1];
}
}
}
for(int i=1;i<=q;i++){
int x1=read(),y1=read(),x2=read(),y2=read(),h=read(),l=1,r=1000,res=-1;
while(l<=r){
int mid=l+r>>1;
if(f[x2][y2][mid]-f[x2][y1-1][mid]-f[x1-1][y2][mid]+f[x1-1][y1-1][mid]>=h){
l=mid+1,res=mid;
}else r=mid-1;
}if(res==-1){
cout<<"Poor QLW\n";
}else{
cout<<fs[x2][y2][res]-fs[x2][y1-1][res]-fs[x1-1][y2][res]+fs[x1-1][y1-1][res]-(f[x2][y2][res]-f[x2][y1-1][res]-f[x1-1][y2][res]+f[x1-1][y1-1][res]-h)/r<<'\n';
}
}
}
return 0;
}