POJ_3233
如果我们把S(k)写成递推式的话,就是S(k)=A*S(k-1)+A,这样就可以将S(k)表示成矩阵的形式,从而应用二分矩阵来快速求解S(k)了。
此外,在计算中间结果的时候尽量少取模,因为取模运算的效率确实很低。
#include<stdio.h> #include<string.h> #define MAXD 70 int N, K, M, cnt; struct Matrix { int a[MAXD][MAXD]; void init() { memset(a, 0, sizeof(a)); } }mat[510]; int multiply(int x, int y) { int i, j, k, z = ++ cnt; long long ans; for(i = 0; i < (N << 1); i ++) for(j = 0; j < (N << 1); j ++) { ans = 0; for(k = 0; k < (N << 1); k ++) ans += mat[x].a[i][k] * mat[y].a[k][j]; mat[z].a[i][j] = ans % M; } return z; } void init() { int i, j, k; cnt = 0; mat[0].init(); for(i = 0; i < N; i ++) for(j = 0; j < N; j ++) { scanf("%d", &k); mat[0].a[i][j] = mat[0].a[i][j + N] = k; if(i == j) mat[0].a[i + N][j + N] = 1; } } int powmod(int n) { int k; if(n == 1) return 0; k = powmod(n / 2); k = multiply(k, k); if(n & 1) k = multiply(k, 0); return k; } void solve() { int i, j, k; k = powmod(K); for(i = 0; i < N; i ++) { printf("%d", mat[k].a[i][N]); for(j = 1; j < N; j ++) printf(" %d", mat[k].a[i][j + N]); printf("\n"); } } int main() { while(scanf("%d%d%d", &N, &K, &M) == 3) { init(); solve(); } return 0; }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单