[国家集训队] 矩阵乘法 题解
发现实际上就是二维静态区间最大值,可以用整体二分维护。
时间复杂度 \(O((q+n^2)\log \max(a_{i,j})\log n^2)\)。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int W=310005;
const int Q=6e4+5;
int n,q,w,ans[Q];
int c[505][505],m;
void add(int x,int y,int k){
for(;x<=n;x+=x&-x)
for(int i=y;i<=n;i+=i&-i)
c[x][i]+=k;
}int sum(int x,int y){
if(x<1||y<1) return 0;
int re=0;
for(;x;x-=x&-x)
for(int i=y;i;i-=i&-i)
re+=c[x][i];
return re;
}struct que{
int x,y,z,w,e,o,id;
}p[W],p1[W],p2[W];
void dichot(int l,int r,int ql,int qr){
if(ql>qr) return;
if(l==r){
for(int i=ql;i<=qr;i++)
if(!p[i].o) ans[p[i].id]=l;
return;
}int t1=0,t2=0,mid=(l+r)/2;
for(int i=ql;i<=qr;i++){
if(p[i].o){
if(p[i].z<=mid){
add(p[i].x,p[i].y,1);
p1[++t1]=p[i];
}else p2[++t2]=p[i];
continue;
}int x=sum(p[i].z,p[i].w);
int y=sum(p[i].z,p[i].y-1);
int z=sum(p[i].x-1,p[i].w);
int a=sum(p[i].x-1,p[i].y-1);
int sm=x-y-z+a;
if(p[i].e>sm){
p[i].e-=sm;
p2[++t2]=p[i];
}else p1[++t1]=p[i];
}for(int i=1;i<=t1;i++)
if(p1[i].o) add(p1[i].x,p1[i].y,-1);
for(int i=1;i<=t1;i++) p[i+ql-1]=p1[i];
for(int i=1;i<=t2;i++) p[i+ql+t1-1]=p2[i];
dichot(l,mid,ql,t1+ql-1);
dichot(mid+1,r,t1+ql,qr);
}int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>p[++w].z,p[w].x=i,p[w].y=j,p[w].o=1;
for(int i=1;i<=w;i++) m=max(m,p[i].z);
for(int i=1;i<=q;i++)
p[++w].id=i,cin>>p[w].x>>p[w].y>>p[w].z>>p[w].w>>p[w].e;
dichot(0,m+1,1,w);
for(int i=1;i<=q;i++)
cout<<ans[i]<<"\n";
return 0;
}//Kaká