[国家集训队] 矩阵乘法 题解

发现实际上就是二维静态区间最大值,可以用整体二分维护。

时间复杂度 \(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á
posted @ 2024-05-04 09:38  长安一片月_22  阅读(3)  评论(0编辑  收藏  举报