题意:求A + A^2 + A^3 + ... + A^m。

析:主要是两种方式,第一种是倍增法,把A + A^2 + A^3 + ... + A^m,拆成两部分,一部分是(E + A^(m/2))(A + A^2 + A^3 + ... + A^(m/2)),然后依次计算下去,就可以分解,logn的复杂度分解,注意要分奇偶。

另一种是直接构造矩阵,,然后就可以用辞阵快速幂计算了,注意要用分块矩阵的乘法。

代码如下:

倍增法:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e3 + 10;
const int mod = 10;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r > 0 && r <= n && c > 0 && c <= m;
} struct Matrix{
int a[40][40];
int n; friend Matrix operator + (const Matrix &lhs, const Matrix &rhs){
Matrix res;
res.n = lhs.n;
for(int i = 0; i < lhs.n; ++i)
for(int j = 0; j < lhs.n; ++j)
res.a[i][j] = (lhs.a[i][j] + rhs.a[i][j]) % mod;
return res;
} friend Matrix operator * (const Matrix &lhs, const Matrix &rhs){
Matrix res;
res.n = lhs.n;
for(int i = 0; i < lhs.n; ++i)
for(int j = 0; j < lhs.n; ++j){
res.a[i][j] = 0;
for(int k = 0; k < lhs.n; ++k)
res.a[i][j] += lhs.a[i][k] * rhs.a[k][j];
res.a[i][j] %= mod;
}
return res;
}
}; Matrix E; Matrix fast_pow(Matrix a, int m){
Matrix res;
res.n = n;
memset(res.a, 0, sizeof res.a);
for(int i = 0; i < res.n; ++i)
res.a[i][i] = 1;
while(m){
if(m & 1) res = res * a;
m >>= 1;
a = a * a;
}
return res;
} Matrix dfs(int m, Matrix x){
if(m == 1) return x;
if(m == 0) return E;
Matrix ans = (E + fast_pow(x, m/2)) * dfs(m/2, x);
if(m & 1) ans = ans + fast_pow(x, m);
return ans;
} int main(){
while(scanf("%d %d", &n, &m) == 2 && n){
Matrix x; x.n = n;
E.n = n;
memset(E.a, 0, sizeof E.a);
for(int i = 0; i < n; ++i)
E.a[i][i] = 1;
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j){
scanf("%d", &x.a[i][j]);
x.a[i][j] %= mod;
} Matrix ans = dfs(m, x);
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
if(j + 1 == n) printf("%d\n", ans.a[i][j]);
else printf("%d ", ans.a[i][j]);
printf("\n");
}
return 0;
}

  

构造法:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e3 + 10;
const int mod = 10;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r > 0 && r <= n && c > 0 && c <= m;
} struct Node{
int a[80][80]; friend void add(const Node &lhs, const Node &rhs, Node &res, int x, int y, int l, int r){
for(int i = x; i < y; ++i)
for(int j = l; j < r; ++j)
res.a[i][j] = (lhs.a[i-x][j-l] + rhs.a[i-x][j-l]) % mod;
} friend void solve(int x, int y, int l, int r, int p, int q, const Node &lhs, const Node &rhs, Node &res){
for(int i = x; i < y; ++i)
for(int j = l; j < r; ++j){
res.a[i-x][j-l] = 0;
for(int k = p; k < q; ++k)
res.a[i-x][j-l] += lhs.a[i][k] * rhs.a[k][j];
}
} friend Node operator * (const Node &lhs, const Node &rhs){
Node res, x, y;
solve(0, n, 0, n, 0, n, lhs, rhs, x);
solve(0, n, 0, n, n, n+n, lhs, rhs, y);
add(x, y, res, 0, n, 0, n); solve(0, n, n, n+n, 0, n, lhs, rhs, x);
solve(0, n, n, n+n, n, n+n, lhs, rhs, y);
add(x, y, res, 0, n, n, n+n); solve(n, n+n, 0, n, 0, n, lhs, rhs, x);
solve(n, n+n, 0, n, n, n+n, lhs, rhs, y);
add(x, y, res, n, n+n, 0, n); solve(n, n+n, n, n+n, 0, n, lhs, rhs, x);
solve(n, n+n, n, n+n, n, n+n, lhs, rhs, y);
add(x, y, res, n, n+n, n, n+n); return res;
}
}; Node fast_pow(Node a, int m){
Node res;
memset(res.a, 0, sizeof res.a);
for(int i = 0; i < n; ++i)
res.a[i][i] = res.a[i+n][i] = 1; while(m){
if(m & 1) res = res * a;
m >>= 1;
a = a * a;
}
return res;
} int main(){
while(scanf("%d %d", &n, &m) == 2 && n){
Node x, y;
memset(y.a, 0, sizeof y.a);
for(int i = 0; i < n; ++i)
for(int j = n; j < n+n; ++j){
scanf("%d", &y.a[i][j]);
y.a[i][j] %= mod;
}
for(int i = 0; i < n; ++i)
y.a[i][i] = 1;
for(int i = n; i < n + n; ++i)
for(int j = n; j < n + n; ++j)
y.a[i][j] = y.a[i-n][j];
memset(x.a, 0, sizeof x.a);
for(int i = n; i < n+n; ++i)
x.a[i][i-n] = 1; Node ans = fast_pow(y, m); if(m) ans = ans * x;
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
if(j == n-1) printf("%d\n", ans.a[i][j]);
else printf("%d ", ans.a[i][j]);
printf("\n");
}
return 0;
}

  

UVa 11149 Power of Matrix (矩阵快速幂,倍增法或构造矩阵)的更多相关文章

  1. UVA 11149.Power of Matrix-矩阵快速幂倍增

    Power of Matrix UVA - 11149       代码: #include <cstdio> #include <cstring> #include < ...

  2. UVA - 11149 (矩阵快速幂+倍增法)

    第一道矩阵快速幂的题:模板题: #include<stack> #include<queue> #include<cmath> #include<cstdio ...

  3. UVA 11149 - Power of Matrix(矩阵乘法)

    UVA 11149 - Power of Matrix 题目链接 题意:给定一个n*n的矩阵A和k,求∑kiAi 思路:利用倍增去搞.∑kiAi=(1+Ak/2)∑k/2iAi,不断二分就可以 代码: ...

  4. BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)

    题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...

  5. UVA 11149 Power of Matrix

    矩阵快速幂. 读入A矩阵之后,马上对A矩阵每一个元素%10,否则会WA..... #include<cstdio> #include<cstring> #include< ...

  6. Luogu P3390 【模板】矩阵快速幂&&P1939 【模板】矩阵加速(数列)

    补一补之前的坑 因为上次关于矩阵的那篇blog写的内容太多太宽泛了,所以这次把一些板子和基本思路理一理 先看这道模板题:P3390 [模板]矩阵快速幂 首先我们知道矩阵乘法满足结合律而不满足交换律的一 ...

  7. 2019 牛客暑期多校 B generator 1 (矩阵快速幂+倍增)

    题目:https://ac.nowcoder.com/acm/contest/885/B 题意:给你x0,x1,让你求出xn,递推式时xn=a*xn-1+b*xn-2 思路:这个n特别大,我自己没有摸 ...

  8. UVa 11149 Power of Matrix(倍增法、矩阵快速幂)

    题目链接: 传送门 Power of Matrix Time Limit: 3000MS      Description 给一个n阶方阵,求A1+A2+A3+......Ak. 思路 A1+A2+. ...

  9. UVA 11149 Power of Matrix 快速幂

    题目链接: http://acm.hust.edu.cn/vjudge/contest/122094#problem/G Power of Matrix Time Limit:3000MSMemory ...

随机推荐

  1. Rancher使用入门

    http://tonybai.com/2016/04/14/an-introduction-about-rancher/

  2. 图像处理笔记(1): bmp文件结构处理与显示

    1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个重要因素是它可视化的漂亮界面.那么Windows是如何显示图象的呢? ...

  3. Go基本语句

    递增递减语句 在GO中,++与--是作为语句而并不是作为表达式 package main import "fmt" func main() { a:= //a=a++ //语句而非 ...

  4. Linux Change The I/O Scheduler For A Hard Disk

    ow do I change the I/O scheduler for a particular hard disk without rebooting my Linux server system ...

  5. MinGW下载并配置gcc/g++编译环境

    本文将讲解如何下载MinGW并配置gcc\g++编译环境 一.下载MinGW 在MinGW官网中下载“mingw-get-setup.exe” 官网传送门:http://www.mingw.org/  ...

  6. mysql事务之二:MySQL隔离级别演示

    登录mysql: mysql -u root -p123456 Mysql 版本号 mysql> select version(); +-------------------------+ | ...

  7. Quartz 用 cron 表达式存放执行计划

    Quartz 用 cron 表达式存放执行计划.引用了 cron 表达式的 CronTrigger 在计划的时间里会与 job 关联上. 1.Quartz cron 表达式支持七个域如下: 名称 是否 ...

  8. 解决git gnutls_handshake失败

    sudo apt-get install build-essential fakeroot dpkg-dev mkdir ~/git-openssl cd ~/git-openssl sudo apt ...

  9. http协议Keep-Alive

    Keep-Alive 是什么? 概观 默认情况下,HTTP链接通常在请求完成之后关闭.这意味着服务端在完成响应的交付之后便关闭了TCP链接.为了让链接保持打开,来满足多请求,可以使用keep-aliv ...

  10. Python函数的初识

    一   什么是函数 定义: 定义一个事情或者功能,等到需要用的时候直接用就可以了,那么这个定义的就是一个函数 函数  :  对代码块和功能的封装和定义 函数定义的格式:     def   函数名() ...