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

    Description

    给出矩阵的行数 (n) 和列数 (m),矩阵 (A_{i,j} = lcm( i , j )),求每个大小为 (k imes k) 的子矩阵的最大值的和。(n,m le 5000)

    Solution

    关键在于如何求出 gcd 矩阵,剩下的可以单调队列处理

    考虑从每一对互质数对 ((i,j)) 开始,将所有 ((ki,kj)) 的 gcd 设为 (k)

    这个过程显然是 (O(nm)) 的,因为每对数最多只会被设置一次 gcd

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 5005;
    
    int n,m,k,a[N][N],b[N][N];
    deque<pair<int,int>> q;
    
    vector<int> getmax(vector<int> s)
    {
        vector<int> ans;
        q.clear();
        int n=s.size();
        for(int i=0;i<k-1;i++)
        {
            while(q.size() && q.back().first<s[i]) q.pop_back();
            q.push_back({s[i],i});
        }
        for(int i=k-1;i<n;i++)
        {
            while(q.size() && q.back().first<s[i]) q.pop_back();
            q.push_back({s[i],i});
            while(q.size() && q.front().second<=i-k) q.pop_front();
            ans.push_back(q.front().first);
        }
        return ans;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(b[i][j]==0)
                {
                    for(int k=1;k<=min(n/i,m/j);k++)
                    {
                        b[i*k][j*k]=k;
                        a[i*k][j*k]=i*j*k;
                    }
                }
            }
        }
        for(int i=0;i<n;i++)
        {
            vector<int> vec;
            for(int j=0;j<m;j++) vec.push_back(a[i+1][j+1]);
            vector<int> ans=getmax(vec);
            for(int j=0;j<=m-k;j++) b[i][j]=ans[j];
        }
        for(int j=0;j<=m-k;j++)
        {
            vector<int> vec;
            for(int i=0;i<n;i++) vec.push_back(b[i][j]);
            vector<int> ans=getmax(vec);
            for(int i=0;i<=n-k;i++) a[i][j]=ans[i];
        }
        long long ans=0;
        for(int i=0;i<=n-k;i++)
        {
            for(int j=0;j<=m-k;j++)
            {
                ans+=a[i][j];
            }
        }
        cout<<ans<<endl;
    }
    
    
  • 相关阅读:
    python之字符串【str】
    python之列表【list】
    python之os模块
    MySQL 模糊查询
    Dreamoon-Operating on a graph(并查集+链表)
    Dreamoon-Operation Love(凸包)
    CF1382D.Unmerge(背包)
    PAT-T1027 Larry and Inversions (树状数组)
    CF1379C.Choosing Flowers(二分)
    矩阵快速幂模板
  • 原文地址:https://www.cnblogs.com/mollnn/p/13308696.html
Copyright © 2011-2022 走看看