Drind @ 2024-05-04 16:20:56
RT,我也不知道为什么,总之挂了。
#include<bits/stdc++.h>
using namespace std;
const int N=5e2+10;
const int M=6e4+10;
const int inf=1e9;
inline int _abs(int x){if(x>0) return x;return -x;}
struct BIT{//二维树状树组
int tree[N][N];
int lowbit(int x){
return x&(-x);
}
void modify(int x,int y,int val){
while(x<N){
int ty=y;
while(ty<N){
tree[x][ty]+=val;
ty+=lowbit(ty);
}
x+=lowbit(x);
}
}
int q(int x,int y){
int ans=0;
while(x){
int ty=y;
while(ty){
ans+=tree[x][ty];
ty-=lowbit(ty);
}
x-=lowbit(x);
}
return ans;
}
int query(int x,int y,int _x,int _y){//(x,y) left-up (_x,_y) right-down
return q(_x,_y)-q(_x,y-1)-q(x-1,_y)+q(x-1,y-1);
}
}bit;
struct queries{
int l,r,_l,_r,id,opt,k;
}t[M+N*N]; int F[M],cnt1,cnt2,cnt;
queries q1[M+N*N],q2[M+N*N];
void solve(int l,int r,int L,int R){
if(l>r) return;//没东西了 就return
//cout<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
//for(int i=l;i<=r;i++){
// cout<<t[i].l<<" "<<t[i].r<<" "<<t[i]._l<<" "<<t[i]._r<<" "<<t[i].id<<" "<<t[i].opt<<" "<<t[i].k<<"\n";
//}
if(L==R){//如果到一个区间上,就是答案
for(int i=l;i<=r;i++){
if(t[i].opt==1) F[t[i].id]=L;
}
return;
}
int mid=(L+R)>>1; cnt1=cnt2=0;
for(int i=l;i<=r;i++){
if(t[i].opt==0){//如果是数字,就加上去
if(t[i].k<=mid){
bit.modify(t[i].l,t[i].r,1);
q1[++cnt1]=t[i];
}else{
q2[++cnt2]=t[i];
}
}else{//如果是查询,就二分
int tmp=bit.query(t[i].l,t[i].r,t[i]._l,t[i]._r);
//cout<<t[i].id<<" "<<tmp<<"\n";
if(tmp>=t[i].k){
q1[++cnt1]=t[i];
}else{
t[i].k-=tmp;
q2[++cnt2]=t[i];
}
}
}
for(int i=1;i<=cnt1;i++){//树状数组回退
if(q1[i].opt==0) bit.modify(q1[i].l,q1[i].r,-1);
}
//合并左右边
for(int i=1;i<=cnt1;i++) t[l+i-1]=q1[i];
for(int i=1;i<=cnt2;i++) t[l+cnt1+i-1]=q2[i];
solve(l,l+cnt1-1,L,mid);//递归
solve(l+cnt1,r,mid+1,R);
}
int a[N][N];
int qwq[N*N],res;
void fake_main(){
int n,q; cin>>n>>q;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j]; qwq[++res]=a[i][j];
//t[++cnt]={i,j,0,0,0,0,a[i][j]};
}
}
sort(qwq+1,qwq+res+1);//离散化
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j]=lower_bound(qwq+1,qwq+res+1,a[i][j])-qwq;
t[++cnt]={i,j,0,0,0,0,a[i][j]};
}
}
for(int i=1;i<=q;i++){
int l,r,_l,_r,k; cin>>l>>r>>_l>>_r>>k;
t[++cnt]={l,r,_l,_r,i,1,k};
}//存入查询
solve(1,cnt,1,n*n);//二分
for(int i=1;i<=q;i++){
cout<<qwq[F[i]]<<"\n";
}
}
signed main(){
ios::sync_with_stdio(false);
int t; t=1;
while(t--) fake_main();
}
by Drind @ 2024-05-04 17:06:25
@lao_wang 发现问题了,cnt1 应该定义在 solve 函数里面,而不是全局变量。
by lao_wang @ 2024-05-04 17:06:50
@Drind 6
by tjx114514 @ 2024-05-04 17:09:27
整体二分职业哥来亲自指导了
by seika27 @ 2024-05-04 17:14:33
整体二分的最强传说老王之二分
by Yuzimy @ 2024-05-04 17:25:01
@d0j1a_1701 你 tm 谁啊
by Eraine @ 2024-05-04 17:27:24
@d0j1a_1701 你是否缺乏线下单杀?