zoukankan      html  css  js  c++  java
  • BZOJ2738 矩阵乘法

    题目

    给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数。

    思路

    整体二分。

    整体二分主要适用于对于二分状态的改变,可以在可接受的复杂度内修改的题目。

    就本题而言,二分答案,如果考虑将[1,mid]的区间内的点加入树状数组中,在二维平面上标记为1,然后比较每个询问与K的关系,接着将询问分组,接着二分。

    以上应该是整体二分的基本模型。

    代码

    #include<bits/stdc++.h>
    #define M 60005
    using namespace std;
    struct node{
        int x,y,val;
        bool operator < (const node& res)const{
            return val<res.val;
        }
    }B[505*505];
    int n,Q,A[505][505],bcnt,ans[M],t1[M],t2[M];
    int id[M],now;
    struct que{
        int x1,y1,x2,y2,k;
    }wk[M];
    struct BIT{
        int C[505][505];
        void Add(int x,int y,int d){
            x++;y++;
            while(x<=n+1){
                int a=y;
                while(y<=n+1){
                    C[x][y]+=d;
                    y+=(y&-y);
                }   
                y=a;
                x+=(x&-x);
            }
        }
        int sum(int x,int y){
            x++;y++;
            int res=0;
            while(x){
                int a=y;
                while(y){
                    res+=C[x][y];
                    y-=(y&-y);
                }
                y=a;
                x-=(x&-x);
            }
            return res;
        }
    }T;
    void update(int x,int f){
        T.Add(B[x].x,B[x].y,f); 
    }
    int query(int x1,int y1,int x2,int y2){
        return T.sum(x2,y2)-T.sum(x1-1,y2)-T.sum(x2,y1-1)+T.sum(x1-1,y1-1); 
    }
    void solve(int l,int r,int ql,int qr){
        if(l>r)return;
        if(ql==qr){
            for(int i=l;i<=r;i++)ans[id[i]]=ql;
            return;
        }
        int mid=(ql+qr)>>1,c1=0,c2=0,c=l-1;
        while(now<mid)update(++now,1);
        while(now>mid)update(now--,-1);
        for(int i=l;i<=r;i++){
            if(query(wk[id[i]].x1,wk[id[i]].y1,wk[id[i]].x2,wk[id[i]].y2)<wk[id[i]].k)t1[++c1]=id[i];
            else t2[++c2]=id[i];
        }
        for(int i=1;i<=c2;i++)id[++c]=t2[i];
        for(int i=1;i<=c1;i++)id[++c]=t1[i];
        solve(l,l+c2-1,ql,mid);solve(l+c2,r,mid+1,qr);
    }
    int main(){
    //  freopen("1.in","r",stdin);
    //  freopen("1.ans","w",stdout);
        scanf("%d%d",&n,&Q);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&A[i][j]),B[++bcnt].val=A[i][j],B[bcnt].x=i,B[bcnt].y=j;
        sort(B+1,B+bcnt+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                int l=1,r=bcnt,res=-1;
                while(l<=r){
                    int mid=(l+r)>>1;
                    if(B[mid].val>=A[i][j]){
                        res=mid;
                        r=mid-1;
                    }
                    else l=mid+1;
                }
                A[i][j]=res;
            }
        for(int i=1;i<=Q;i++){
            scanf("%d%d%d%d%d",&wk[i].x1,&wk[i].y1,&wk[i].x2,&wk[i].y2,&wk[i].k);
            id[i]=i;
        }
        solve(1,Q,1,bcnt);
        for(int i=1;i<=Q;i++){
            printf("%d
    ",B[ans[i]].val);
        }
        return 0;
    }
    
  • 相关阅读:
    [kuangbin带你飞]专题十二 基础DP1 E
    hdu 1203 I NEED A OFFER! (01背包)
    hdu 2602 Bone Collector (01背包)
    hdu 4513 吉哥系列故事——完美队形II (manacher)
    hdu 2203 亲和串 (KMP)
    hdu 1686 Oulipo (KMP)
    hdu 1251 统计难题 (字典树)
    hdu 2846 Repository (字典树)
    hdu 1711 Number Sequence (KMP)
    poj 3461 Oulipo(KMP)
  • 原文地址:https://www.cnblogs.com/zryabc/p/11232030.html
Copyright © 2011-2022 走看看