zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第二场)Fake Maxpooling

    题目链接

    https://ac.nowcoder.com/acm/contest/5667/F

    题目大意

    给你一个 N * N 的矩阵 , 其中第 i 行第 j 列的值为 lcm(i , j) 

    问这个矩阵的所有 K * K 子矩阵的最大值的和为多少

    解题思路 

    比赛的时候硬是用 N^2logN 的做法卡了过去

    这道题有两个考点 : ①、构造矩阵 ②、求出每个子矩阵最大值

    对于考点 ① 构造出矩阵值的最优方案是用类似筛的方法(具体看代码)

    对于考点 ②

    求数列子串的最大值用单调队列维护

    求矩阵的子矩阵的最大值用二维单调队列维护(对行维护一遍 , 然后对列维护一遍)

    AC_Code

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 5e3 + 10;
    int a[N][N] , n , m , k;
    deque<int>que;
    int ma[N][N];
    void get_max(int ma[] , int a[] , int n)
    {
        que.clear();
        for(int i = 1 ; i <= n ; i ++)
        {
            if(!que.empty() && que.front() <= i - k) que.pop_front();
            while(!que.empty() && a[que.back()] <= a[i]) que.pop_back();
            que.push_back(i);
            ma[i] = a[que.front()];
        }
    }
    int b[N] , ra[N];
    signed main()
    {
        ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0);
        cin >> n >> m >> k;
        for(int i = 1 ; i <= n ; i ++) for(int j = 1 ; j <= m ; j ++)
        if(!a[i][j])
        {
            for(int k = 1 ; i * k <= n && j * k <= m ; k ++) a[i * k][j * k] = i * k * j;
        }
        for(int i = 1 ; i <= n ; i ++) get_max(ma[i] , a[i] , m);
        long long res = 0;
        for(int j = k ; j <= m ; j ++)
        {
            for(int i = 1 ; i <= n ; i ++) b[i] = ma[i][j];
            get_max(ra , b , n);
            for(int i = k ; i <= n ; i ++) res += ra[i];
        }
        cout << res << '
    ';
        return 0;
    }
  • 相关阅读:
    Android零碎知识之Style and Theme
    Java 线程池(一):开篇及Executor整体框架介绍
    ADB命令笔记本
    volatile变量理解 via《Java并发编程实战》
    Java NIO
    乱七八糟(一)
    Android事件分发机制
    AndroidStudio下的依赖管理
    shell--填过的坑
    兼容类问题
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/13343908.html
Copyright © 2011-2022 走看看