矩阵幂次之和。

自己想着想着就想到了一个解法,但是还没提交,因为POJ崩了,做了一个FIB的前n项和,也是用了这个方法,AC了,相信是可以得。

提交了,是AC的

http://poj.org/problem?id=3233

我的思路是:

首先原矩阵保留着,然后需要扩大一倍

需要求1--->1的路径数 <= k的,ans = (路径数 = k的) +(路径数 < k)的

等于k的很容易求,就是e^k然后e[1][1]就是答案,那么小于k的,我们需要虚拟一个节点保留着

可以先看看这个http://www.cnblogs.com/liuweimingcprogram/p/6490034.html

然后新增一个节点3,e[1][3] = 1,  e[3][3] = 1是用来求 < k的数目的。

怎么求,比如

这样求到的e[1][1] = 1表明长度是2的有一种情况,但是长度是1的遗漏了,就是1--1本来那条,通过新增一条虚拟边e[1][3]

这样就把1--1原来的那条边保留了下来,

1-->3这条边是专为1服务的,是e[1][1],也就是结尾点是1的情况的总数。所以会有一条e[3][3]的多余边,需要减去1。

而求1-->2的总数的时候,是e[1][2](长度是k的总数) + e[1][4](长度 < k的总数)这里就不会多出一条边了,因为本来的e[1][4] = 0的

这个是真真正正的保留了1--2这条边了。

具体自己画画吧,感觉描述不清楚了。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
struct Matrix {
LL a[maxn][maxn];
int row;
int col;
}base;
//应对稀疏矩阵,更快。
struct Matrix matrix_mul(struct Matrix a, struct Matrix b, int MOD) { //求解矩阵a*b%MOD
struct Matrix c = {}; //这个要多次用到,栈分配问题,maxn不能开太大,
//LL的时候更加是,空间是maxn*maxn的,这样时间用得很多,4和5相差300ms
c.row = a.row; //行等于第一个矩阵的行
c.col = b.col; //列等于第二个矩阵的列
for (int i = ; i <= a.row; ++i) {
for (int k = ; k <= a.col; ++k) {
if (a.a[i][k]) { //应付稀疏矩阵,0就不用枚举下面了
for (int j = ; j <= b.col; ++j) {
c.a[i][j] += a.a[i][k] * b.a[k][j];
c.a[i][j] = (c.a[i][j] + MOD) % MOD; //负数取模
}
}
}
}
return c;
}
struct Matrix quick_matrix_pow(struct Matrix ans, struct Matrix base, int n, int MOD) {
//求解a*b^n%MOD
while (n) {
if (n & ) {
ans = matrix_mul(ans, base, MOD);//传数组不能乱传,不满足交换律
}
n >>= ;
base = matrix_mul(base, base, MOD);
}
return ans;
}
int n, k, MOD;
void work() {
base.row = base.col = * n;
for (int i = ; i <= n; ++i) {
for (int j = ; j <= n; ++j) {
cin >> base.a[i][j];
base.a[i][j] %= MOD;
}
}
for (int i = ; i <= n; ++i) {
base.a[i][n + i] = ;
}
for (int i = n + ; i <= * n; ++i) {
base.a[i][i] = ;
}
// for (int i = 1; i <= 2 * n; ++i) {
// for (int j = 1; j <= 2 * n; ++j) {
// printf("%d ", base.a[i][j]);
// }
// printf("\n");
// }
Matrix I = {};
I.row = I.col = * n;
for (int i = ; i <= * n; ++i) {
I.a[i][i] = ;
}
// printf("\n");
I = quick_matrix_pow(I, base, k, MOD);
// for (int i = 1; i <= 2 * n; ++i) {
// for (int j = 1; j <= 2 * n; ++j) {
// printf("%d ", I.a[i][j]);
// }
// printf("\n");
// }
for (int i = ; i <= n; ++i) {
for (int j = ; j <= n; ++j) {
int ans = ;
ans += I.a[i][j];
ans += I.a[i][n + j];
ans %= MOD;
if (i == j) ans = (ans - + MOD) % MOD;
printf("%d ", ans);
}
printf("\n");
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
while (cin >> n >> k >> MOD) work();
return ;
}

做了这个题

http://acm.hdu.edu.cn/showproblem.php?pid=5171

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = ;
struct Matrix {
LL a[maxn][maxn];
int row;
int col;
}base;
//应对稀疏矩阵,更快。
struct Matrix matrix_mul(struct Matrix a, struct Matrix b, int MOD) { //求解矩阵a*b%MOD
struct Matrix c = {}; //这个要多次用到,栈分配问题,maxn不能开太大,
//LL的时候更加是,空间是maxn*maxn的,这样时间用得很多,4和5相差300ms
c.row = a.row; //行等于第一个矩阵的行
c.col = b.col; //列等于第二个矩阵的列
for (int i = ; i <= a.row; ++i) {
for (int k = ; k <= a.col; ++k) {
if (a.a[i][k]) { //应付稀疏矩阵,0就不用枚举下面了
for (int j = ; j <= b.col; ++j) {
c.a[i][j] += a.a[i][k] * b.a[k][j];
c.a[i][j] = (c.a[i][j] + MOD) % MOD; //负数取模
}
}
}
}
return c;
}
struct Matrix quick_matrix_pow(struct Matrix ans, struct Matrix base, int n, int MOD) {
//求解a*b^n%MOD
while (n) {
if (n & ) {
ans = matrix_mul(ans, base, MOD);//传数组不能乱传,不满足交换律
}
n >>= ;
base = matrix_mul(base, base, MOD);
}
return ans;
}
const int MOD = ;
int n, k;
int a[ + ];
void work() {
for (int i = ; i <= n; ++i) cin >> a[i];
sort(a + , a + + n);
Matrix I = {};
I.row = I.col = ;
for (int i = ; i <= ; ++i) I.a[i][i] = ;
I = quick_matrix_pow(I, base, k, MOD);
Matrix F = {};
F.row = , F.col = ;
F.a[][] = a[n], F.a[][] = a[n - ];
Matrix b = {};
b.row = b.col = ;
for (int i = ; i <= ; ++i) {
for (int j = ; j <= ; ++j) {
int ans = I.a[i][j];
ans += I.a[i][ + j];
ans %= MOD;
if (i == j) ans = (ans - + MOD) % MOD;
b.a[i][j] = ans;
}
}
// for (int i = 1; i <= 2; ++i) {
// for (int j = 1; j <= 2; ++j) {
// printf("%d ", b.a[i][j]);
// }
// printf("\n");
// }
F = matrix_mul(F, b, MOD);
int ans = F.a[][];
for (int i = ; i <= n; ++i) {
ans = (ans + a[i]) % MOD;
}
cout << ans << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
base.col = base.row = ;
base.a[][] = , base.a[][] = ;
base.a[][] = , base.a[][] = ;
for (int i = ; i <= ; ++i) {
base.a[i][ + i] = ;
}
for (int i = ; i <= ; ++i) base.a[i][i] = ;
while (cin >> n >> k) work();
return ;
}

Matrix Power Series POJ - 3233 矩阵幂次之和。的更多相关文章

  1. Matrix Power Series(POJ 3233)

    原题如下: Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 28044   Acce ...

  2. POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】

    任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K To ...

  3. [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15417   Accepted:  ...

  4. POJ 3233 Matrix Power Series --二分求矩阵等比数列和

    题意:求S(k) = A+A^2+...+A^k. 解法:二分即可. if(k为奇)  S(k) = S(k-1)+A^k else        S(k) = S(k/2)*(I+A^(k/2)) ...

  5. 矩阵十点【两】 poj 1575 Tr A poj 3233 Matrix Power Series

    poj 1575  Tr A 主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575 题目大意:A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的 ...

  6. Matrix Power Series

    Matrix Power Series 给出矩阵A,求矩阵\(A+A^2+...+A^k\)各个元素\(mod\ yyb\)的值,\(n\leq 30,k\leq 10^9,yyb\leq 10^4\ ...

  7. POJ 3233 Matrix Power Series(矩阵快速幂)

    Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 19338 Accepted: 8161 ...

  8. poj 3233 Matrix Power Series(矩阵二分,高速幂)

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15739   Accepted:  ...

  9. POJ 3233:Matrix Power Series 矩阵快速幂 乘积

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 18450   Accepted:  ...

随机推荐

  1. mysql基础之三:char与varchar区别,varchar(M)能存多少

    char与varchar区别 char (13)长度固定, 如'1234567890' 存储需要空间 10个字符; varchar(13) 可变长 如'1234567890' 需要存储空间 11字符; ...

  2. WPF 导出Excel(合并单元格)

    WPF 导出Excel(合并单元格) DataTable 导出Excel(导出想要的列,不想要的去掉) ,B1,B2,B3,B4,B5} MisroSoft.Office.Interop.Excel. ...

  3. 问题:部署到iis上后Chart图片不显示;结果:使用webchart过程中遇到的一些问题

    使用webchart过程中遇到的一些问题 2013年04月30日 ⁄ 综合 ⁄ 共 4874字 ⁄ 字号 小 中 大 ⁄ 评论关闭   安装条件:1.操作系统如果是2003的,那么需要到sp2补丁2. ...

  4. 服务器修改密码cmd

    net user  账号  要修改的密码

  5. oracle 新增字段

    alter table shop_procategory add (category_ORDER_FIELD number(10) default '0' not null);comment on c ...

  6. 内核启动流程3--Busybox的init进程

    Busybox是用来制作文件系统的一个工具集,可以用来替换GNU fileutils shellutils等工具集,它为各种小型的或者嵌入式系统提供了比较完全的工具集. 它提供的核心程序中包括了用户空 ...

  7. 阶段3-团队合作\项目-网络安全传输系统\sprint1-传输子系统设计\第3课-加密传输优化

    对之前的传输系统进行加密,使之成为加密的网络传输系统 客户端编程模型 通过以上模型对传统的TCP传输模型进行优化 首先完成初始化工作,它是要在创建socket之前完成 主要是以上四个函数的实现,那么这 ...

  8. Struts2学习第七课 OGNL

    request变成了struts重写的StrutsRequestWrapper 关于值栈: helloWorld时,${productName}读取productName值,实际上该属性并不在requ ...

  9. java的大小端和转换

    一直以为大小端针对的bit的顺序,今天才知道:大小端的分度值是 byte,即每一个byte都是按照正常顺序,但是byte组装成一个int 或者是 long等时每个byte的摆放位置不同. 测试代码: ...

  10. H5 简介

    HTML5 - 新特性 HTML5 的一些最有趣的新特性: 新的语义元素,比如 <header>, <footer>, <article>, and <sec ...