Power of Matrix

prologue

因为格式问题被卡了一小时的人是谁我不说。

analysis

首先这个题目如果我们暴力计算的话,时间复杂度是不允许的(矩阵乘法前面有巨大的常数)。

那么我们就考虑怎么用一些巧妙地方法去计算。我们就可以采取两次分治地思想,递归求解。

以下结论显然成立,读者自证不难:

A1+A2++Ak=A1++Amid+Amid(A1++Amid)

这个就是我们能够递归求解的本质。我们就可以将原来的 Ak 转换成一个可以递归求解的式子,具体如下:

  1. k=1,则直接返回当前矩阵。
  2. k1,则可以继续递归计算,得出一小段和的值,然后再进行快速幂运算算出来i=1(k>>1)<<1Ai,这里并不是直接到 k 是因为我们对于奇数来说要进行特殊判断。(这里的位运算写的很抽象我知道 /fad)
  3. k 为奇数,则我们应当再加上一个 Ak

接下来就是我们的代码实现了,但是还有一个要注意的:

每一行的最后没有空格!!!,每一个测试数据之后都要输出换行!!!!

code time

**#include <bits/stdc++.h> using namespace std; #define ll long long #define rl register ll #define foa(i, a, b) for(rl i=a; i < b; ++ i) #define fos(i, a, b) for(rl i=a; i <= b; ++ i) #define fop(i, a, b) for(rl i=a; i >= b; -- i) #define ws putchar(' ') #define wl putchar('\n') template <class T> inline void waw(T x) { if(x > 9) waw(x / 10); putchar(x % 10 ^ 48); } template <class T> inline void ww(T x) { if(x < 0) x = ~x + 1, putchar('-'); waw(x); } template <class T> inline void read(T &res) { char ch = getchar(); bool f = 0; res = 0; for(; !isdigit(ch); ch = getchar()) f |= ch == '-'; for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch ^ 48); res = f ? ~res + 1 : res; } const ll N = 45; ll n, m; struct Matrix { ll a[N][N]; Matrix () { memset(a, 0, sizeof a); } inline void init() {memset(a, 0, sizeof a); } Matrix operator +(const Matrix &x) const { Matrix res; foa(i, 0, n) foa(j, 0, n) res.a[i][j] = (a[i][j] + x.a[i][j]) % 10; return res; } Matrix operator *(const Matrix &x) const { Matrix res; foa(i, 0, n) foa(k, 0, n) foa(j, 0, n) res.a[i][j] = (res.a[i][j] + (a[i][k] * x.a[k][j]) % 10) % 10; return res; } } a; inline Matrix qmi(Matrix t, ll k) { Matrix res = t; -- k; while(k) { if(k & 1) res = res * t; t = t * t; k >>= 1; } return res; } inline Matrix calc(Matrix t,ll k) { if(k == 1) {return t; } // border cases Matrix ans, tmp = calc(t, k >> 1); ans = tmp + (tmp * qmi(t, k >> 1)); if(k & 1) ans = ans + qmi(t, k); return ans; } int main() { while(scanf("%lld%lld", &n, &m) && n) { a.init(); foa(i, 0, n) foa(j, 0, n) read(a.a[i][j]), a.a[i][j] %= 10; Matrix ans = calc(a, m); foa(i, 0, n) { foa(j, 0, n) { waw(ans.a[i][j]); if(j != n - 1) ws; } wl; } wl; } return 0; }

__EOF__

本文作者carp
本文链接https://www.cnblogs.com/carp-oier/p/17766570.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   carp_oier  阅读(17)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示