1 条题解

  • 0
    @ 2025-5-12 18:26:38

    矩阵和模最大值问题题解

    这个问题涉及到一个三维矩阵中的模运算优化,主要考察前缀和数组、二分查找和集合操作的综合应用。

    问题分析

    问题描述: 给定一个3行N列的矩阵,每列有三个值。要求找到一个分割点k,使得以下表达式的值最大:

    (S1[k] - S2[k-1]) mod M + (S3[N] - S3[k-1] + S2[k]) mod M
    

    其中S1、S2、S3分别是三行的前缀和数组,M是给定的模数。

    关键思路

    1. 预处理三行的前缀和数组
    2. 枚举分割点k,维护一个集合存储前面所有k的(S1[k] - S2[k-1]) mod M值
    3. 对于每个k,在集合中查找使得第二个表达式值最大的元素

    解题思路

    1. 前缀和数组

      • 计算每行的前缀和数组,其中pre[i][j]表示第i行前j个元素的和模M的值
    2. 枚举分割点

      • 对于每个分割点k,计算两个关键值:
        • x1 = (pre[1][k] - pre[2][k-1]) mod M
        • x2 = (pre[3][N] - pre[3][k-1] + pre[2][k]) mod M
    3. 集合优化

      • 使用一个有序集合维护所有前面计算过的x1值
      • 对于每个x2,在集合中查找小于等于(mod - x2)的最大元素,以最大化(x2 + y) mod M

    代码实现分析

    关键数据结构

    const int MAXN = 100100;
    long long mz[5][MAXN], pre[5][MAXN]; // 存储矩阵和前缀和数组
    set<long long> st; // 维护x1值的有序集合
    

    前缀和计算

    pre[1][0] = pre[2][0] = pre[3][0] = 0;
    for(i = 1; i <= 3; i++)
        for(j = 1; j <= n; j++)
            pre[i][j] = (mz[i][j] + pre[i][j-1]) % mod;
    

    枚举分割点并维护集合

    st.clear();
    ans = 0;
    for(i = 1; i <= n; i++)
    {
        x1 = (pre[1][i] - pre[2][i-1] + mod) % mod;
        st.insert(x1); // 将当前x1加入集合
        
        x2 = (pre[3][n] - pre[3][i-1] + pre[2][i] + mod) % mod;
        it = st.lower_bound(mod - x2); // 查找第一个不小于(mod - x2)的元素
        ans = max(ans, (x2 + *(--it)) % mod); // 取前一个元素,计算最大值
    }
    

    主函数处理流程

    int main()
    {
        long long n, mod, i, j, ans, x1, x2;
        while(~scanf("%lld%lld", &n, &mod))
        {
            // 读取矩阵
            for(i = 1; i <= 3; i++)
                for(j = 1; j <= n; j++)
                    scanf("%lld", &mz[i][j]);
            
            // 计算前缀和
            // ...
            
            // 枚举分割点并计算最大值
            // ...
            
            printf("%lld\n", ans);
        }
    }
    

    复杂度分析

    • 时间复杂度O(NlogN)O(N log N),其中N是矩阵的列数。主要是枚举每个分割点并在集合中进行查找操作。
    • 空间复杂度O(N)O(N),主要用于存储前缀和数组和集合。

    这个算法通过预处理前缀和数组和使用有序集合快速查找最优解,高效地解决了问题。集合的lower_bound操作确保了每次查找的时间复杂度为O(log N),使得整体算法能够处理较大的输入规模。

    • 1

    信息

    ID
    625
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者