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

给定一串操作,要这个操作连续执行m次后,最后剩下的值。

记矩阵T为一次操作后的值,那么T^m就是执行m次的值了。(其实这个还不太理解,但是数据一相乘,就是ans)

构造一个0--n的单位矩阵,用第0行作为各个猫的值,这样的话,用A={1,0,0,0}一乘就是每个毛的ans。

构造单位矩阵的意义就是他们矩阵自己相乘的时候,能够保留自己的值。

这个矩阵很分散,0的那些可以特判掉不枚举多一程O(n)了。这需要你的矩阵乘法是一个一个加上去的,而不是集中一起加上去的。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
struct Matrix {
LL a[maxn][maxn];
int row;
int col;
};
struct Matrix c; //这个要多次用到,栈分配问题,maxn不能开太大,
struct Matrix matrix_mul (struct Matrix a,struct Matrix b,int MOD) {
//求解矩阵a*b%MOD
struct Matrix c = {};
//LL的时候更加是,空间是maxn*maxn的,这样时间用得很多
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]) {//应付稀疏矩阵
for (int j = ; j <= b.col; ++j) {
c.a[i][j] += a.a[i][k] * b.a[k][j];
}
}
}
}
return c;
}
struct Matrix quick_matrix_pow (struct Matrix ans,struct Matrix base,int n,int MOD) {
//求解a*b^n%MOD
// cout << n << endl;
while (n) {
if (n&) {
ans=matrix_mul(ans,base,MOD);//传数组不能乱传,不满足交换律
}
n>>=;
base=matrix_mul(base,base,);
}
return ans;
}
int n, m, k;
void work() {
struct Matrix b = {};
b.row = b.col = n;
for (int i = ; i <= n; ++i) {
b.a[i][i] = ;
}
for (int i = ; i <= k; ++i) {
char str[];
int a, c;
scanf("%s", str);
if (str[] == 'g') {
scanf("%d", &a);
++b.a[][a];
} else if (str[] == 'e') {
scanf("%d", &a);
for (int j = ; j <= n; ++j) {
b.a[j][a] = ;
}
} else {
scanf("%d%d", &a, &c);
for (int j = ; j <= n; ++j) {
swap(b.a[j][a], b.a[j][c]);
}
}
}
// for (int i = 0; i <= n; ++i) {
// for (int j = 0; j <= n; ++j) {
// cout << b.a[i][j] << " ";
// }
// cout << endl;
// }
struct Matrix tt = {};
tt.row = ;
tt.col = n;
tt.a[][] = ;
struct Matrix ans = quick_matrix_pow(tt, b, m, );
for (int i = ; i <= n; ++i) {
printf("%lld ", ans.a[][i]);
}
printf("\n");
}
int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
while (scanf("%d%d%d", &n, &m, &k) != EOF && n + m + k) work();
return ;
}

最新文章

  1. WPF入门教程系列十七——WPF中的数据绑定(三)
  2. js调用页面打印
  3. SpringMVC学习--数据回显
  4. Div内部的内容超出部分显示省略号(仅仅只有一行内容)
  5. Javascript history pushState onpopstate方法做AJAX SEO
  6. redis模块
  7. centos安装lxml和pyspider
  8. spring mvc controller间跳转 重定向
  9. Springmvc默认首页的问题
  10. dotweb框架之旅 [二] - 常用对象-App(dotweb)
  11. 阿里Dubbo疯狂更新,关Spring Cloud什么事?
  12. UmengAppDemo【友盟统计SDK集成以及多渠道打包配置,基于V7.5.3版本】
  13. mapper代理查询
  14. springboot 事务管理
  15. java 中 正则 matches vs find
  16. linux 常用命令--------雪松整理
  17. java 数据结构与算法---队列
  18. Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations 矩阵快速幂优化dp
  19. centos top命令列解释
  20. django执行过程

热门文章

  1. k8s-集群状态及部署一个实例
  2. 洛谷 P2919 [USACO08NOV]守护农场Guarding the Farm
  3. mysql建表练习
  4. javaweb学习总结—监听器(Listener)
  5. &lt;正则吃饺子&gt; :关于oracle 中 with的简单使用
  6. js中关于事件捕获与事件冒泡的小实验
  7. 你所不知道的html5与html中的那些事(五)——web图像
  8. PCL推荐的命名规范(2)
  9. Gym 101142C CodeCoder vs TopForces (搜索)
  10. POJ - 3268 Silver Cow Party SPFA+SLF优化 单源起点终点最短路