Niu Ke summer multi-school 200713F Fake Maxpooling LCM/Monotone Queue

Link: https://ac.nowcoder.com/acm/contest/5667/F
Source : Niuke.com

This topic is last

meaning of the title

Each element of an n * m matrix is ​​the least common multiple of the row number and the column number.
What is the sum of the maximum values ​​of all k * k submatrices of your matrix.

ideas

I checked some methods and said that the two-dimensional st table can also be used, but many people say that it is feasible, so it is feasible .
I feel that the monotonous queue saves a little space (does it?)
.
First O(n * m) to find the matrix A
and then use the monotonic queue for each row to find the maximum of the k elements of each element starting from the current element,
and then use the monotonic queue for each column to be similar to the row.
Note that the maximum value is required to make the monotonic queue a decreasing queue.

code

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define sdd(a,b) scanf("%d%d",&a,&b)
#define cl(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define sddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define dbg() printf("aaa\n")
using namespace std;
const int maxn=5010;
int n,m,k;
int a[maxn][maxn];//存放最小公倍数
int b[maxn][maxn];//存放从这个点开始 之后的k个数里最大的是多少
struct node{
    
    
    int val,p;//值和位置
};
deque<node> q;
int main() {
    
    
	sddd(n,m,k);
    cl(a,0);
    cl(b,0);
    rep(i,1,n){
    
    
        rep(j,1,m){
    
    
            if(a[i][j]==0){
    
    
                for(int k=1;i*k<=n&&j*k<=m;k++){
    
    //这个方法很妙 自己只会暴力
                    a[i*k][j*k]=i*j*k;
                }
            }
        }
    }//现在已经得到了矩阵的值
    rep(i,1,n){
    
    //对于每一行
        while(!q.empty()) q.pop_front();//求最大值 就递减吧
        rep(j,1,m){
    
    
            node tp;
            tp.val=a[i][j];
            tp.p=j;
            while(!q.empty()&&tp.val>q.back().val){
    
    
                q.pop_back();
            }
            q.push_back(tp);
            if(j-q.front().p>=k){
    
    
                q.pop_front();
            }
            if(j>=k){
    
    
                b[i][j-k+1]=q.front().val;
            }
        }
    }
    ll sum=0;//最后结果可能爆int!!!!!
    rep(j,1,m-k+1){
    
    //对于每一列
        while(!q.empty()) q.pop_front();
        rep(i,1,n){
    
    
            node tp;
            tp.val=b[i][j];
            tp.p=i;
            while(!q.empty()&&tp.val>q.back().val){
    
    
                q.pop_back();
            }
            q.push_back(tp);
            if(i-q.front().p>=k){
    
    
                q.pop_front();
            }
            if(i>=k){
    
    
                b[i-k+1][j]=q.front().val;
                sum+=b[i-k+1][j];
            }
        }
    }
    printf("%lld\n",sum);
	return 0;
}

topic

Title description
Given a matrix of size n\times mn×m and an integer {k}k, where A_{i,j} = lcm(i, j)A
i,j=lcm(i,j), the least common multiple of {i}i and {j}j. You should determine the sum of the maximums among all k\times kk×k submatrices.
Input description:
Only one line containing three integers n,m,k~(1\leq n ,m \leq 5000, 1 \leq k \leq \min{n, m})n,m,k (1≤n,m≤5000,1≤k≤min{n,m}).
Output description:
Only one line containing one integer, denoting the answer.
Example 1
input
copy
3 4 2
output
copy
38
Description
The given matrix is:
1 2 3 4
2 2 6 4
3 6 3 12
The maximums among all 2\times 22×2 submatrices are {2, 6, 6, 6, 6, 12}2,6,6,6,6,12 respectively, and their sum is {38}38.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326146927&siteId=291194637