[POJ3735]Training little cats
题目: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的更多相关文章
- 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 ...
- poj3735—Training little cats(特殊操作转化为矩阵操作)
题目链接:http://poj.org/problem?id=3735 题目意思: 调教猫咪:有n只饥渴的猫咪,现有一组羞耻连续操作,由k个操作组成,全部选自: 1. g i 给第i只猫咪一颗花生 2 ...
- Training little cats poj3735
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9299 Accepted: 2 ...
- Training little cats(poj3735,矩阵快速幂)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10737 Accepted: ...
- [poj3735] Training little cats_矩乘快速幂
Training little cats poj-3735 题目大意:给你n个数,k个操作,将所有操作重复m次. 注释:三种操作,将第i个盒子+1,交换两个盒子中的个数,将一个盒子清空.$1\le m ...
- 矩阵快速幂 POJ 3735 Training little cats
题目传送门 /* 题意:k次操作,g:i猫+1, e:i猫eat,s:swap 矩阵快速幂:写个转置矩阵,将k次操作写在第0行,定义A = {1,0, 0, 0...}除了第一个外其他是猫的初始值 自 ...
- [POJ 3735] Training little cats (结构矩阵、矩阵高速功率)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9613 Accepted: 2 ...
- POJ 3735 Training little cats<矩阵快速幂/稀疏矩阵的优化>
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13488 Accepted: ...
- POJ 3735 Training little cats(矩阵快速幂)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11787 Accepted: 2892 ...
随机推荐
- maven项目 @Resource报错 ava.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;
@Resource 出错 java.lang.NoSuchMethodError: javax.annotation.Resource.lookup() maven项目中,使用@Resource报错. ...
- 【Unity知识点】安卓游戏如何在切后台后继续运行
解决方法很简单,在android项目AndroidManifest.xml文件中的activity中添加如下内容: android:configChanges="fontScale|keyb ...
- std::map使用结构体自定义键值
使用STL中的map时候,有时候需要使用结构题自定义键值,比如想统计点的坐标出现的次数 struct Node{ int x,y; }; ...... map<Node,int>mp; m ...
- 08 (h5*) js第9天--原型、继承
目录: 1:原型和原型链 2:构造函数的原型可以改变 3:原型的最终指向 4:先修改原型指向,在添加方法. 5:实例对象中的属性和原型属性重合, 6:一个神奇的原型链 7:继承 8:原型链 9:利用c ...
- java创建线程的两种方式及源码解析
创建线程的方式有很多种,下面我们就最基本的两种方式进行说明.主要先介绍使用方式,再从源码角度进行解析. 继承Thread类的方式 实现Runnable接口的方式 这两种方式是最基本的创建线程的方式,其 ...
- Quartz-第一篇 认识Quartz
1.什么是Quartz Quartz是一个任务调度框架,借助Cron表达式,Quartz可以支持各种复杂的任务调度.JDK中也提供了简单的任务调度,java.util.Timer. Quartz的三大 ...
- SVN合并主干分支的方法
第一步 第二步 第三步 第四步
- 【转】通俗理解Java序列化与反序列化
一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存 ...
- 理解Throughput和Latency
Throughput,中文译作吞吐量.Latency,中文译作延迟.它们是衡量软件系统的最常见的两个指标. 吞吐量一般指相当一段时间内测量出来的系统单位时间处理的任务数或事务数(TPS).注意“相当一 ...
- 独立成分分析(Independent Component Analysis)
ICA是一种用于在统计数据中寻找隐藏的因素或者成分的方法.ICA是一种广泛用于盲缘分离的(BBS)方法,用于揭示随机变量或者信号中隐藏的信息.ICA被用于从混合信号中提取独立的信号信息.ICA在20世 ...