zoukankan      html  css  js  c++  java
  • BZOJ2738:矩阵乘法——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2738

    Description

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

    Input

    第一行两个数N,Q,表示矩阵大小和询问组数;
    接下来N行N列一共N*N个数,表示这个矩阵;
    再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。

    Output

    对于每组询问输出第K小的数。

    Sample Input

    2 2
    2 1
    3 4
    1 2 1 2 1
    1 1 2 2 3

    Sample Output

    1
    3

    整体二分二维版。

    只需要把树状数组变成二维即可。

    完后我们就对所有可行的取值二分然后就是整体二分的板子了。

    (当然你也可以离散化)

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    using namespace std;
    const int N=510;
    const int Q=6e4+5;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct square{
        int val,x,y;
    }v[N*N];
    bool cmp(square a,square b){
        return a.val<b.val;
    }
    struct question{
        int lx,rx,ly,ry,k,id;
    }q[Q],tmp1[Q],tmp2[Q];
    int ans[Q],tr[N][N];
    int n,m,cnt;
    inline int lowbit(int t){return t&(-t);}
    inline void add(int x,int y,int z){
        for(int i=x;i<=n;i+=lowbit(i))
            for(int j=y;j<=n;j+=lowbit(j))
                tr[i][j]+=z;
    }
    inline int qry(int x,int y){
        int res=0;
        for(int i=x;i;i-=lowbit(i))
            for(int j=y;j;j-=lowbit(j))
                res+=tr[i][j];
        return res;
    }
    void solve(int L,int R,int l,int r){
        if(L>R)return;
        if(l==r){
            for(int i=L;i<=R;i++)ans[q[i].id]=v[l].val;
            return;
        }
        int idx1=0,idx2=0,mid=(l+r)>>1;
        for(int i=l;i<=mid;i++)add(v[i].x,v[i].y,1);
        for(int i=L;i<=R;i++){
            int sum=qry(q[i].rx,q[i].ry)+
                    qry(q[i].lx-1,q[i].ly-1)-
                    qry(q[i].rx,q[i].ly-1)-
                    qry(q[i].lx-1,q[i].ry);
            if(sum>=q[i].k)tmp1[idx1++]=q[i];
            else q[i].k-=sum,tmp2[idx2++]=q[i];
        }
        for(int i=l;i<=mid;i++)add(v[i].x,v[i].y,-1);
        int MID=L+idx1;
        for(int i=L;i<MID;i++)q[i]=tmp1[i-L];
        for(int i=MID;i<=R;i++)q[i]=tmp2[i-MID];
        solve(L,MID-1,l,mid);solve(MID,R,mid+1,r);
        return;
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                v[++cnt].val=read();
                v[cnt].x=i,v[cnt].y=j;
            }
        }
        sort(v+1,v+cnt+1,cmp);
        for(int i=1;i<=m;i++){
            q[i].lx=read();q[i].ly=read();
            q[i].rx=read();q[i].ry=read();
            q[i].k=read();q[i].id=i;
        }
        solve(1,m,1,cnt);
        for(int i=1;i<=m;i++)printf("%d
    ",ans[i]);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    bootstrap表格
    Bootstrap的学习
    cssText文本格式化
    for循环坐标生成《逢五向上转》
    for循环坐标生成《逢十往下一行》
    for
    bootstrap学习笔记细化(表格)
    bootstrap学习笔记细化(按钮)
    bootstrap学习笔记细化(表单)
    bootstrap学习笔记细化(标题)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8387178.html
Copyright © 2011-2022 走看看