Matrix Power Series POJ - 3233 矩阵幂次之和。
矩阵幂次之和。
自己想着想着就想到了一个解法,但是还没提交,因为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 矩阵幂次之和。的更多相关文章
- Matrix Power Series(POJ 3233)
原题如下: Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 28044 Acce ...
- POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】
任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K To ...
- [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: ...
- 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)) ...
- 矩阵十点【两】 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的迹(就是主对角线上各项的 ...
- 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\ ...
- POJ 3233 Matrix Power Series(矩阵快速幂)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 19338 Accepted: 8161 ...
- poj 3233 Matrix Power Series(矩阵二分,高速幂)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 15739 Accepted: ...
- POJ 3233:Matrix Power Series 矩阵快速幂 乘积
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 18450 Accepted: ...
随机推荐
- mysql基础之三:char与varchar区别,varchar(M)能存多少
char与varchar区别 char (13)长度固定, 如'1234567890' 存储需要空间 10个字符; varchar(13) 可变长 如'1234567890' 需要存储空间 11字符; ...
- WPF 导出Excel(合并单元格)
WPF 导出Excel(合并单元格) DataTable 导出Excel(导出想要的列,不想要的去掉) ,B1,B2,B3,B4,B5} MisroSoft.Office.Interop.Excel. ...
- 问题:部署到iis上后Chart图片不显示;结果:使用webchart过程中遇到的一些问题
使用webchart过程中遇到的一些问题 2013年04月30日 ⁄ 综合 ⁄ 共 4874字 ⁄ 字号 小 中 大 ⁄ 评论关闭 安装条件:1.操作系统如果是2003的,那么需要到sp2补丁2. ...
- 服务器修改密码cmd
net user 账号 要修改的密码
- oracle 新增字段
alter table shop_procategory add (category_ORDER_FIELD number(10) default '0' not null);comment on c ...
- 内核启动流程3--Busybox的init进程
Busybox是用来制作文件系统的一个工具集,可以用来替换GNU fileutils shellutils等工具集,它为各种小型的或者嵌入式系统提供了比较完全的工具集. 它提供的核心程序中包括了用户空 ...
- 阶段3-团队合作\项目-网络安全传输系统\sprint1-传输子系统设计\第3课-加密传输优化
对之前的传输系统进行加密,使之成为加密的网络传输系统 客户端编程模型 通过以上模型对传统的TCP传输模型进行优化 首先完成初始化工作,它是要在创建socket之前完成 主要是以上四个函数的实现,那么这 ...
- Struts2学习第七课 OGNL
request变成了struts重写的StrutsRequestWrapper 关于值栈: helloWorld时,${productName}读取productName值,实际上该属性并不在requ ...
- java的大小端和转换
一直以为大小端针对的bit的顺序,今天才知道:大小端的分度值是 byte,即每一个byte都是按照正常顺序,但是byte组装成一个int 或者是 long等时每个byte的摆放位置不同. 测试代码: ...
- H5 简介
HTML5 - 新特性 HTML5 的一些最有趣的新特性: 新的语义元素,比如 <header>, <footer>, <article>, and <sec ...