• 洛谷1527 [国家集训队]矩阵乘法(整体二分)


    题意:给你一个的矩阵,每次询问一个子矩形的第 k小数

    输入格式:第一行有两个整数,分别表示矩阵大小 n和询问组数 q

    第 2到第 (n + 1)行,每行 n个整数,表示这个矩阵。第 (i + 1)行的第 j个数表示矩阵第 i行第 j列的数ai,j

    接下来 q行,每行五个整数x1,y1,x2,y2,k,表示一组询问,要求找到以(x1,y1)为左上角,(x2,y2)为右下角的子矩形中的第 k小数

    输出格式:对于每组询问,输出一行一个整数表示答案。

    #include<cstdio>
    #include<algorithm>
    const int N = 505;
    const int M = 6e4 + 5;
    
    struct Matrix{
        int x, y, val;
        bool operator <(const Matrix &u)const{
            return val < u.val;
        }
    }matrix[N * N];
    
    struct Query{
        int x1, y1, x2, y2, k;
    }q[M];
    
    struct BIT{
        int n, m;
        int c[N][N];
    
        inline void init(int x, int y) { n = x, m = y; }
        inline int lowbit(int &x) { return x & -x; }
    
        void modify(int x, int y, int p){
            for(int i = x; i <= n; i += lowbit(i))
                for(int t = y; t <= m; t += lowbit(t)){
                    c[i][t] += p;
                }
        }
    
        int query(int x,int y){
            int ans = 0;
            for(int i = x; i; i -= lowbit(i))
                for(int t = y; t; t -= lowbit(t)){
                    ans += c[i][t];
                }
            return ans;
        }
    
        int Query(Query p){
            return query(p.x2, p.y2) + query(p.x1 - 1, p.y1 - 1) - query(p.x1 - 1, p.y2) - query(p.x2, p.y1 - 1);
        }
    }Tree;
    
    int n, m, tot;
    int ans[M], id[M], cur[M], t1[M], t2[M];
    
    void solve(int l, int r, int ql, int qr){    // 二分值域
        if(ql > qr)  return ;        //该值域区间没有询问
        if(l == r){
            for(int i = ql; i <= qr; ++i)  ans[id[i]] = matrix[l].val;
            return ;    // 找到解
        }
        int mid = (l + r) >> 1;
        for(int i = l; i <= mid; ++i)  Tree.modify(matrix[i].x, matrix[i].y, 1);
        int cl = 0, cr = 0;
        for(int i = ql; i <= qr; ++i){
            int u = id[i];    // 当前要处理的询问
            int s = cur[u] + Tree.Query(q[u]);    // 加上当前区间中位于q[u]询问矩阵范围内的点
            if(s >= q[u].k)  t1[++cl] = u;
            else  t2[++cr] = u, cur[u] = s;
        }
        int kk = ql - 1;
        for(int i = 1; i <= cl; ++i)  id[++kk] = t1[i];     // 左右分组
        for(int i = 1; i <= cr; ++i)  id[++kk] = t2[i];
        for(int i = l; i <= mid; ++i)  Tree.modify(matrix[i].x, matrix[i].y, -1);
        solve(l, mid, ql, ql + cl - 1);
        solve(mid + 1, r, ql + cl, qr);
    }
    
    int main(){
        scanf("%d%d", &n, &m);
        Tree.init(n, n);
        for(int i = 1, val; i <= n; ++i)
            for(int t = 1; t <= n; ++t){
                scanf("%d", &val);
                matrix[++tot] = Matrix{i, t, val};
            }
        std::sort(matrix + 1, matrix + 1 + tot);
        for(int i = 1; i <= m; ++i)  id[i] = i;
        for(int i = 1; i <= m; ++i)
            scanf("%d%d%d%d%d", &q[i].x1, &q[i].y1, &q[i].x2, &q[i].y2, &q[i].k);
        solve(1, tot, 1, m);
        for(int i = 1; i <= m; ++i)  printf("%d
    ", ans[i]);
        return 0;
    }
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    Python 常用内置函数
    Java Graphics 2D绘制图片 在Liunx上乱码
    LInux Centos7 重装yum
    Spring Boot 异步调用
    Linux 清除N天前的 日期文件夹(yyyy-MM-dd)
    Python 2.75升级3.6.3
    Linux 移除python Error: Trying to remove “yum”, which is protected
    Java Future 使用场景
    CF446D DZY Loves Games
    三 lambda表达式有什么用
  • 原文地址:https://www.cnblogs.com/214txdy/p/14024389.html
Copyright © 2020-2023  润新知