题意:求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. FastAdmin 2018-05-26 更新时更新了 SQL 文件 关于 ROW_FORMAT=DYNAMIC 改为 ROW_FORMAT=COMPACT 问题

    FastAdmin 2018-05-26 更新时更新了 SQL 文件 关于 ROW_FORMAT=DYNAMIC 改为 ROW_FORMAT=COMPACT 问题 观查到 FastAdmin 在 20 ...

  2. JAX-RS之queryparam、PathParam、DefaultValue、FormParam、Context、RestController等

    这几天做东西接触了JAX-RS的东西,没有系统的从开始就学,只是单纯去复制粘贴的用,主要用到了几个Annotations变量,具体如下: queryparam.PathParam.FormParam. ...

  3. C++ 中的 new/delete 和 new[]/delete[]

    在 C++ 中,你也许经常使用 new 和 delete 来动态申请和释放内存,但你可曾想过以下问题呢? new 和 delete 是函数吗? new [] 和 delete [] 又是什么?什么时候 ...

  4. 普及组2008NOIP 排座椅(贪心+排序)

    排座椅 时间限制: 1 Sec  内存限制: 50 MB提交: 4  解决: 3[提交][状态][讨论版][命题人:外部导入] 题目描述 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任 ...

  5. 第十五届浙江省赛 F Now Loading!!!

    Now Loading!!! Time Limit: 1 Second      Memory Limit: 131072 KB DreamGrid has  integers . DreamGrid ...

  6. PHP实现日志写入log.txt

    引言:有时候调试,看不到效果,需要通过写入文件来实现. 案例: <?php $myfile = fopen("log.txt", "a+") or die ...

  7. 实战MvcPager(PagerOptions自定义样式&同、异步)

    ASP.NET MVC下的分页控件MvcPager用起来简直太嗨呸了,两句代码实现一个分页,而且需要改变样式的时候直接构造PagerOptions类 实战无需多说,拿来用之即可.个人觉得对性能影响不大 ...

  8. PHP字符串的处理(一)-字符串初识和比较

    在PHP中,字符和字节一样,共有256种不同字符的可能性,PHP对Unicode没有本地支持,一个GB2312编码的汉字占2字节,一个UTF-8编码的汉字占3字节字符串看作字符集和时,并不是真正的数组 ...

  9. 界面主窗体,子窗体的InitializeComponent(构造函数)、Load事件执行顺序

    主窗体,子窗体的InitializeComponent(构造函数).Load事件执行顺序1.执行主窗体定义事件 new函数时,同时执行主窗体构造函数,默认就一个InitializeComponent函 ...

  10. HDFS案例

    shell日志采集 需求说明 点击流日志每天都10T,在业务应用服务器上,需要准实时上传至数据仓库(Hadoop HDFS)上 需求分析 一般上传文件都是在凌晨24点操作,由于很多种类的业务数据都要在 ...