构造矩阵

构造矩阵

我们希望构造一个 n×m 的整数矩阵。

构造出的矩阵需满足:

  • 每一行上的所有元素之积均等于 k
  • 每一列上的所有元素之积均等于 k

保证 k11

请你计算,一共可以构成出多少种不同的满足条件的矩阵。

由于结果可能很大,你只需要输出对 109+7 取模后的结果。

输入格式

共一行,包含三个整数 n,m,k

输出格式

一个整数,表示对 109+7 取模后的结果。

数据范围

3 个测试点满足 1n,m3
所有测试点满足 1n,m1018k11

输入样例1:

1 1 -1

输出样例1:

1

输入样例2:

1 3 1

输出样例2:

1

输入样例3:

3 3 -1

输出样例3:

16

 

解题思路

  首先由于只能填整数且乘积不是 1 就是 1,因此只能填 11。对于一个 n×m 的矩阵,先把最后一行和最后一列空出来,那么剩余的部分的大小就是 (n1)×(m1),有 2(n1)×(m1) 种填法。填完后对于前 n1行中的第 r 行,由于每一行的乘积是 k,因此最后一列的 (r,m) 这个位置填的数字就唯一确定了,即 ki=1m1ar,i。同理由于每一列的乘积是 k,因此最后一行的前 m1 列也是唯一确定的。

  最后对于 (n,m) 这个位置的元素,既要满足第 n 行的乘积是 k,也要满足第 m 列的乘积是 k。假设 (n1)×(m1) 大小的矩阵的乘积是 c,最后一行的前 m1 列的乘积是 a,最后一列的前 n1 行的乘积是 b,那么我们会得到 ac=2n1bc=2m1。如果 (n,m) 存在解,那么应该有 a=b,即 2n1=2m1。分情况讨论,如果 k=1,那么等式必然成立。否则 k=1,那么 nm 的奇偶性相同等式才能成立。因此无解的条件是 k=1nm 的奇偶性不同。

  接下来就是计算 2(n1)×(m1),很明显 (n1)×(m1) 会爆 long long,因此可以用 __int128。另外一个做法是写成 (2n1)m1,求两次快速幂即可。还有一种做法是用费马小定理。因为有 ap11(modp),其中 p 是质数,gcd(a,p)=1,因此有 2(n1)×(m1)2(n1)×(m1)modp1(modp)

  AC 代码如下:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

int qmi(int a, __int128 k) {
    int ret = 1;
    while (k) {
        if (k & 1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return ret;
}

int main() {
    LL n, m;
    int k;
    scanf("%lld %lld %d", &n, &m, &k);
    if (k == -1 && (n - 1) % 2 != (m - 1) % 2) printf("0");
    else printf("%d", qmi(2, (__int128)(n - 1) * (m - 1)));
    
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

int qmi(int a, LL k) {
    int ret = 1;
    while (k) {
        if (k & 1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return ret;
}

int main() {
    LL n, m;
    int k;
    scanf("%lld %lld %d", &n, &m, &k);
    if (k == -1 && (n - 1) % 2 != (m - 1) % 2) printf("0");
    else printf("%d", qmi(qmi(2, n - 1), m - 1));
    
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

int qmi(int a, int k) {
    int ret = 1;
    while (k) {
        if (k & 1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return ret;
}

int main() {
    LL n, m;
    int k;
    scanf("%lld %lld %d", &n, &m, &k);
    if (k == -1 && (n - 1) % 2 != (m - 1) % 2) printf("0");
    else printf("%d", qmi(2, (n - 1) % (mod - 1) * ((m - 1) % (mod - 1)) % (mod - 1)));
    
    return 0;
}

 

参考资料

  AcWing 5284. 构造矩阵(AcWing杯 - 周赛):https://www.acwing.com/video/5188/

posted @   onlyblues  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-10-30 Next Greater Element IV(附带个人感想)
Web Analytics
点击右上角即可分享
微信分享提示