题目:Training little cats

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

分析:

1)将操作用矩阵表示出来,然后快速幂优化。

2)初始矩阵:$ \left[ \begin{array}{ccccc} 1 & a_1 & a_2 & ... & a_n \end{array} \right] $

构造一个$ (n+1)*(n+1) $ 的单位矩阵T。

得花生:将第0行中得到花生的那一列赋为1.

$ \left[ \begin{array}{cccccc} 1 & 0 & ... & [1] & ... & 0 \\ 0 & 1 & ... & 0 & ... & 0 \\ ... & ... & ... & ... & ... & ... \\ 0 & 0 & ... & 0 & ... & 1 \end{array} \right] $

吃花生:将第得到花生的那一行那一列的元素赋为0;

$ \left[ \begin{array}{cccccc} 1 & 0 & ... & 0 & ... & 0 \\ 0 & 1 & ... & 0 & ... & 0 \\ ... & ... & ... & ... & ... & ... \\ 0 & 0 & ... & [0] & ... & 0 \\ ... & ... & ... & ... & ... & ... \\ 0 & 0 & ... & 0 & ... & 1 \end{array} \right] $

交换花生:就是交换两行,就是初等行变化。

$ \left[ \begin{array}{cccccc} 1 & 0 & ... & 0 & ... & 0 \\ ... & ... & ... & ... & ... & ... \\ ... & ... & 0 & ... & [1] & ... \\ ... & ... & ... & ... & ... & ... \\ ... & ... & [1] & ... & 0 & ... \\ ... & ... & ... & ... & ... & ... \\ 0 & 0 & ... & 0 & ... & 1 \end{array} \right] $

3)T不停累乘操作矩阵,最后得到这一组的组操作矩阵。

4)快速幂求T^n,然后第一行就是答案。

5)注意longlong,虽然只有$10^9$次组操作,但每组操作都是100个得花生,还都给一只猫,就爆int了。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
struct Matrix{
int n;
LL a[][];
void init(int _n,int f,int p=,int pp=){
n=_n;
memset(a,,sizeof a);
if(f==-)return;
for(int i=;i<=n;++i)a[i][i]=;
if(f==)a[][p]=;
if(f==)a[p][p]=;
if(f==){
a[p][p]=a[pp][pp]=;
a[p][pp]=a[pp][p]=;
}
}
};
Matrix operator*(Matrix& A,Matrix& B){
Matrix C;C.init(A.n,-);
for(int k=,n=C.n;k<=n;++k)
for(int i=;i<=n;++i)if(A.a[i][k])
for(int j=;j<=n;++j)
C.a[i][j]+=A.a[i][k]*B.a[k][j];
return C;
}
Matrix operator^(Matrix A,int n){
Matrix Rt;Rt.init(A.n,);
for(;n;n>>=){
if(n&)Rt=Rt*A;
A=A*A;
}
return Rt;
}
int main(){
int n,m,k,p,pp;char ch[];
Matrix T,T1;
for(;scanf("%d%d%d",&n,&m,&k);){
if(n== && m== && k==)break;
T.init(n,);
for(int i=;i<=k;++i){
scanf("%s",ch);
switch(ch[]){
case 'g':scanf("%d",&p);T1.init(n,,p);break;
case 'e':scanf("%d",&p);T1.init(n,,p);break;
case 's':scanf("%d%d",&p,&pp);T1.init(n,,p,pp);
}
T=T*T1;
}
T=T^m;
for(int i=;i<=n;++i)printf("%lld ",T.a[][i]);
puts("");
}
return ;
}

6)可以直接把初始矩阵的效果叠加到T上面

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
struct Matrix{
int n;
LL a[][];
void init(int _n,int f){
n=_n;
memset(a,,sizeof a);
if(f==-)return;
for(int i=;i<=n;++i)a[i][i]=;
}
};
Matrix operator*(Matrix& A,Matrix& B){
Matrix C;C.init(A.n,-);
for(int k=,n=C.n;k<=n;++k)
for(int i=;i<=n;++i)if(A.a[i][k])
for(int j=;j<=n;++j)
C.a[i][j]+=A.a[i][k]*B.a[k][j];
return C;
}
Matrix operator^(Matrix A,int n){
Matrix Rt;Rt.init(A.n,);
for(;n;n>>=){
if(n&)Rt=Rt*A;
A=A*A;
}
return Rt;
}
int main(){
int n,m,k,p,pp;char ch[];
Matrix T;
for(;scanf("%d%d%d",&n,&m,&k);){
if(n== && m== && k==)break;
T.init(n,);
for(int i=;i<=k;++i){
scanf("%s",ch);
switch(ch[]){
case 'g':scanf("%d",&p);++T.a[][p];break;
case 'e':scanf("%d",&p);
for(int i=;i<=n;++i)T.a[i][p]=;
break;
case 's':scanf("%d%d",&p,&pp);
for(int i=;i<=n;++i)swap(T.a[i][p],T.a[i][pp]);
}
}
T=T^m;
for(int i=;i<=n;++i)printf("%lld ",T.a[][i]);
puts("");
}
return ;
}

[POJ3735]Training little cats的更多相关文章

  1. xiaowuga poj3735—Training little cats(特殊操作转化为矩阵操作)

    题意:有n只猫,对其进行k次操作,然后反复这样操作m次. 其中g 表示 i 猫加1, e表示 i 猫为0:s表示  i 与 j 猫互换. 解释一下样例: 3 1 6g 1g 2g 2s 1 2g 3e ...

  2. poj3735—Training little cats(特殊操作转化为矩阵操作)

    题目链接:http://poj.org/problem?id=3735 题目意思: 调教猫咪:有n只饥渴的猫咪,现有一组羞耻连续操作,由k个操作组成,全部选自: 1. g i 给第i只猫咪一颗花生 2 ...

  3. Training little cats poj3735

    Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9299   Accepted: 2 ...

  4. Training little cats(poj3735,矩阵快速幂)

    Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10737   Accepted:  ...

  5. [poj3735] Training little cats_矩乘快速幂

    Training little cats poj-3735 题目大意:给你n个数,k个操作,将所有操作重复m次. 注释:三种操作,将第i个盒子+1,交换两个盒子中的个数,将一个盒子清空.$1\le m ...

  6. 矩阵快速幂 POJ 3735 Training little cats

    题目传送门 /* 题意:k次操作,g:i猫+1, e:i猫eat,s:swap 矩阵快速幂:写个转置矩阵,将k次操作写在第0行,定义A = {1,0, 0, 0...}除了第一个外其他是猫的初始值 自 ...

  7. [POJ 3735] Training little cats (结构矩阵、矩阵高速功率)

    Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9613   Accepted: 2 ...

  8. POJ 3735 Training little cats<矩阵快速幂/稀疏矩阵的优化>

    Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13488   Accepted:  ...

  9. POJ 3735 Training little cats(矩阵快速幂)

    Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11787 Accepted: 2892 ...

随机推荐

  1. sysbench - 数据库功能及性能测试工具

    sysbench 的 GitHub 参考资料 1.0 之后的版本使用方法跟之前的有所区别,下面所有内容基于 1.0.9 版本. 另外,为了方便管理测试,最好不要通过命令直接运行测试,而是写成脚本自动化 ...

  2. Android深度探索-卷1第八章心得体会

    本章介绍了如何将Linux驱动分成多个实现文件和Linux常用的代码重用方式还有些强行卸载Linux驱动的方法 开发一个Linux驱动,可能会在init.exit等函数中发生错误导致Linux驱动安装 ...

  3. SpringMVC请求处理流程源码

    我们首先引用<Spring in Action>上的一张图来了解Spring MVC 的核心组件和大致处理流程: 从上图中看到①.DispatcherServlet 是SpringMVC ...

  4. Java单链表

    一.概述 二.主方法 //创建头结点 private HeroNode head = new HeroNode(-1,null,null); //计数器,用于id的自增 private static ...

  5. python:while循环语句及练习题

    while循环语句及练习题 Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.其基本形式为: while 判断条件: 执行语句... ...

  6. 关于URL和URI的最简单理解

    以下面网址为例: http://www.sina.com/news/1.html 那么,http://www.sina.com/news/1.html就表示URL,用于标识互联网中的某一资源:/new ...

  7. jquery实现按键增加删除css属性(hide)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. setter getter 方法

    MRC下setter.getter方法写法.重写dealloc方法 @interface People : NSObject @property (nonatomic,strong) NSString ...

  9. Introduction to Sound Programming with ALSA

    ALSA stands for the Advanced Linux Sound Architecture. It consists of a set of kernel drivers, an ap ...

  10. Redis线上环境做Keys匹配操作!你可以离职了!

    转自:https://blog.csdn.net/bntx2jsqfehy7/article/details/84207884一.一个新闻 新闻内容如下:php工程师执行redis keys * 导致 ...