这里我选择了一种在线的树状数组的写法,有三个log,比较好写但是跑的比较慢,吸氧才能过
其实和一维的没有区别,都是整体二分值域的思想
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+10; int tr[510][510]; struct node{ int op,x,y,x2,y2,k,id; }q[N],lq[N],rq[N]; int ans[N]; int a[510][510]; int lowbit(int x){ return x&-x; } void add(int x,int y,int c){ int i,j; for(i=x;i<=510;i+=lowbit(i)){ for(j=y;j<=510;j+=lowbit(j)){ tr[i][j]+=c; } } } int sum(int x,int y){ int i,j; int ans=0; for(i=x;i;i-=lowbit(i)){ for(j=y;j;j-=lowbit(j)){ ans+=tr[i][j]; } } return ans; } void solve(int vl,int vr,int ql,int qr){ if(ql>qr){ return ; } int i; int n1=0; int n2=0; if(vl==vr){ for(i=ql;i<=qr;i++){ if(q[i].op==2) ans[q[i].id]=vl; } return ; } int mid=vl+vr>>1; for(i=ql;i<=qr;i++){ if(q[i].op==1){ if(q[i].x2<=mid) add(q[i].x,q[i].y,1),lq[++n1]=q[i]; else rq[++n2]=q[i]; } else{ int n=sum(q[i].x2,q[i].y2)+sum(q[i].x-1,q[i].y-1)-sum(q[i].x2,q[i].y-1)-sum(q[i].x-1,q[i].y2); if(n>=q[i].k){ lq[++n1]=q[i]; } else{ q[i].k-=n; rq[++n2]=q[i]; } } } for(i=ql;i<=qr;i++){ if(q[i].op==1){ if(q[i].x2<=mid) add(q[i].x,q[i].y,-1); } } for(i=1;i<=n1;i++) q[ql+i-1]=lq[i]; for(i=1;i<=n2;i++) q[ql+n1+i-1]=rq[i]; solve(vl,mid,ql,ql+n1-1); solve(mid+1,vr,ql+n1,qr); } int main(){ int n,q1; cin>>n>>q1; int i,j; int cnt=0; for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ cin>>a[i][j]; q[++cnt]=node{1,i,j,a[i][j]}; } } for(i=1;i<=q1;i++){ int x,y,x2,y2,k; scanf("%d%d%d%d%d",&x,&y,&x2,&y2,&k); q[++cnt]=node{2,x,y,x2,y2,k,i}; } solve(0,1e9,1,cnt); for(i=1;i<=q1;i++){ printf("%d\n",ans[i]); } }