• [BZOJ2738]矩阵乘法


    2738: 矩阵乘法

    Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 1629  Solved: 710 [Submit][Status][Discuss]

    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

    HINT

      矩阵中数字是109以内的非负整数;
      20%的数据:N<=100,Q<=1000;
      40%的数据:N<=300,Q<=10000;
      60%的数据:N<=400,Q<=30000;
      100%的数据:N<=500,Q<=60000。

    整体二分,二维树状数组维护

    国庆作业还没做要炸了。。。有时间具体写

    Update:

    把数字看成插入按照权值排序

    然后二分答案,将权值小于等于二分值的全部插入

    对于一个询问如果在区间内已经有足够多的数那么就可行

    插入和删除可以用二维树状数组维护

    #pragma GCC optimize ("O2") 
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int n = 0;
        while(*++ptr < '0' || *ptr > '9');
        while(*ptr >= '0' && *ptr <= '9') n = (n << 1) + (n << 3) + (*ptr++ & 15);
        return n; 
    }
    const int maxn = 500 + 10, maxq = 60000 + 10;
    int N, Q;
    int Fen[maxn][maxn] = {0};
    inline void Update(const int &x, const int &y, const int &val){
        for(int i = x; i <= N; i += i & -i)
            for(int j = y; j <= N; j += j & -j)
                Fen[i][j] += val;
    }
    inline int Query(const int &x, const int &y){
        int s = 0;
        for(int i = x; i; i -= i & -i)
            for(int j = y; j; j -= j & -j)
                s += Fen[i][j];
        return s;
    }
    struct Insert{
        int val, x, y;
        Insert(){}
        Insert(int _v, int _x, int _y): val(_v), x(_x), y(_y){}
        bool operator < (const Insert &a) const {
            return val < a.val;
        }
    }a[maxn * maxn];
    int num_cnt = 0;
    struct Question{
        int x1, y1, x2, y2, k;
        void read(){
            x1 = readint();
            y1 = readint();
            x2 = readint();
            y2 = readint();
            k = readint();
        }
    }q[maxq];
    inline int Query(const Question &t){
        return Query(t.x2, t.y2) + Query(t.x1 - 1, t.y1 - 1) - Query(t.x1 - 1, t.y2) - Query(t.x2, t.y1 - 1);
    }
    int ans[maxq];
    int T = 0;
    int id[maxq], tmp[maxq];
    bool mark[maxq];
    void solve(int ql, int qr, int vl, int vr){
        if(ql > qr || vl == vr) return;
        int mid = vl + vr >> 1;
        while(T < N * N && a[T + 1].val <= mid){
            T++;
            Update(a[T].x, a[T].y, 1);
        }
        while(T && a[T].val > mid){
            Update(a[T].x, a[T].y, -1);
            T--;
        }
        int cnt = 0;
        for(int i = ql; i <= qr; i++)
            if(Query(q[id[i]]) >= q[id[i]].k){
                mark[i] = true;
                ans[id[i]] = mid;
                cnt++;
            }
            else mark[i] = false;
        int l1 = ql, l2 = ql + cnt;
        for(int i = ql; i <= qr; i++)
            if(mark[i]) tmp[l1++] = id[i];
            else tmp[l2++] = id[i];
        for(int i = ql; i <= qr; i++) id[i] = tmp[i];
        solve(ql, l1 - 1, vl, mid); solve(l1, qr, mid + 1, vr);
    }
    int main(){
        buf[fread(buf, sizeof(char), sizeof(buf), stdin)] = 0;
        N = readint();
        Q = readint();
        for(int i = 1; i <= N; i++)
            for(int j = 1; j <= N; j++)
                a[++num_cnt] = Insert(readint(), i, j);
        sort(a + 1, a + num_cnt + 1);
        for(int i = 1; i <= Q; i++) q[i].read();
        for(int i = 1; i <= Q; i++) id[i] = i;
        solve(1, Q, 0, a[num_cnt].val + 1);
        for(int i = 1; i <= Q; i++) printf("%d
    ", ans[i]);
        return 0;
    }
  • 相关阅读:
    如何在 Linux 中更改 swappiness
    logrotate机制&原理
    Linux命令 – ln 软连接与硬链接区别介绍
    Python实现目录文件的全量和增量备份
    tr -d命令删除与字符无关的符号
    CentOS7搭建时间服务器-chrony
    linux(centos7.0以上版本)安装 mysql-5.7.24-linux-glibc2.12-x86_64.tar 版本的mysql
    运维相关指标数据采集并ES入仓
    Kubernetes容器集群管理环境
    C++调用IDL程序的做法(三)
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7636973.html
Copyright © 2020-2023  润新知