Training little cats(poj3735,矩阵快速幂)
Training little cats
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 10737 | Accepted: 2563 |
Description
Facer's pet cat just gave birth to a brood of little cats. Having considered the health of those lovely cats, Facer decides to make the cats to do some exercises. Facer has well designed a set of moves for his cats. He is now asking you to supervise the cats to do his exercises. Facer's great exercise for cats contains three different moves:
g i : Let the ith cat take a peanut.
e i : Let the ith cat eat all peanuts it have.
s i j : Let the ith cat and jth cat exchange their peanuts.
All the cats perform a sequence of these moves and must repeat it m times! Poor cats! Only Facer can come up with such embarrassing idea.
You have to determine the final number of peanuts each cat have, and directly give them the exact quantity in order to save them.
Input
The input file consists of multiple test cases, ending with three zeroes "0 0 0". For each test case, three integers n, m and k are given firstly, where n is the number of cats and k is the length of the move sequence. The following k lines describe the sequence.
(m≤1,000,000,000, n≤100, k≤100)
Output
For each test case, output n numbers in a single line, representing the numbers of peanuts the cats have.
Sample Input
3 1 6
g 1
g 2
g 2
s 1 2
g 3
e 2
0 0 0
Sample Output
2 0 1 【题意】:有n只猫咪,开始时每只猫咪有花生0颗,现有一组操作,由下面三个中的k个操作组成:
1. g i 给i只猫咪一颗花生米
2. e i 让第i只猫咪吃掉它拥有的所有花生米
3. s i j 将猫咪i与猫咪j的拥有的花生米交换
现将上述一组操作做m次后,问每只猫咪有多少颗花生?
【题解】:m达到10^9,显然不能直接算。
因为k个操作给出之后就是固定的,所以想到用矩阵,矩阵快速幂可以把时间复杂度降到O(logm)。问题转化为如何构造转置矩阵?
说下我的思路,观察以上三种操作,发现第二,三种操作比较容易处理,重点落在第一种操作上。
有一个很好的办法就是添加一个辅助,使初始矩阵变为一个n+1元组,编号为0到n,下面以3个猫为例:
定义初始矩阵A = [1 0 0 0],0号元素固定为1,1~n分别为对应的猫所拥有的花生数。
对于第一种操作g i,我们在单位矩阵基础上使Mat[0][i]变为1,例如g 1:
1 0 0
0 1 0 0
0 0 1 0
0 0 0 1,显然[1 0 0 0]*Mat = [1 1 0 0]
对于第二种操作e i,我们在单位矩阵基础使Mat[i][i] = 0,例如e 2:
1 0 0 0
0 1 0 0
0 0 0 0
0 0 0 1, 显然[1 2 3 4]*Mat = [1 2 0 4]
对于第三种操作s i j,我们在单位矩阵基础上使第i列与第j互换,例如s 1 3:
1 0 0 0
0 0 0 1
0 0 1 0
0 1 0 0,显然[1 2 0 4]*Mat = [1 4 0 2]
现在,对于每一个操作我们都可以得到一个转置矩阵,把k个操作的矩阵相乘我们可以得到一个新的转置矩阵T。
A * T 表示我们经过一组操作,类似我们可以得到经过m组操作的矩阵为 A * T ^ m,最终矩阵的[0][1~n]即为答案。 上述的做法比较直观,但是实现过于麻烦,因为要构造k个不同矩阵。 有没有别的方法可以直接构造转置矩阵T?答案是肯定的。
我们还是以单位矩阵为基础:
对于第一种操作g i,我们使Mat[0][i] = Mat[0][i] + 1;
对于第二种操作e i,我们使矩阵的第i列清零;
对于第三种操作s i j,我们使第i列与第j列互换。
这样实现的话,我们始终在处理一个矩阵,免去构造k个矩阵的麻烦。 至此,构造转置矩阵T就完成了,接下来只需用矩阵快速幂求出 A * T ^ m即可,还有一个注意的地方,该题需要用到long long。
具体实现可以看下面的代码。 转载请注明出处:寻找&星空の孩子 题目链接:http://poj.org/problem?id=3735
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL __int64
#define mmax 105 struct matrix
{
LL mat[mmax][mmax]; void zero()
{
memset(mat,,sizeof(mat));
}
void unit()
{
for(int i=; i<mmax; i++)
for(int j=; j<mmax; j++)
mat[i][j]=(i==j);
} } A,T; //A = 初始矩阵 ,T = 转置矩阵 int N; matrix multiply(matrix a,matrix b)
{
matrix c;
memset(c.mat,,sizeof(c.mat));
for(int i=; i<N+; i++)
{
for(int j=; j<N+; j++)
{
if(a.mat[i][j]==)continue;
for(int k=; k<N+; k++)
{
if(b.mat[j][k]==)continue;
c.mat[i][k]+=a.mat[i][j]*b.mat[j][k]; }
}
}
return c;
} matrix quicklymod(matrix a,LL n)
{
matrix res;
for(int i=; i<; i++) //单位阵
for(int j=; j<; j++)
res.mat[i][j]=(i==j);
while(n)
{
if(n&)
res=multiply(a,res);
a=multiply(a,a);
n>>=;
}
return res;
} int main()
{
LL m,k;
int x,y;
char ch[];
while(scanf("%d%I64d%I64d",&N,&m,&k)!=EOF)
{
if(!N&&!m&&!k)break;
/* A.zero();
A.mat[0][0]=1;*/
T.unit();
for(int i=; i<k; i++)
{
scanf("%s",ch);
if(ch[]=='g')
{
scanf("%d",&x);
T.mat[][x]++;
}
else if(ch[]=='e')
{
scanf("%d",&x);
for(int i=; i<=N; i++) T.mat[i][x]=;
}
else if(ch[]=='s')
{
scanf("%d%d",&x,&y);
for(int i=; i<=N; i++)
{
swap(T.mat[i][x],T.mat[i][y]);//交换列
}
}
} T=quicklymod(T,m); /* matrix ans = A * (T ^ m);
for(int i = 1; i <= n; i++) printf("%lld ", ans.val[0][i]);
printf("\n");*/
printf("%I64d",T.mat[][]);
for(int i=;i<=N;i++) printf(" %I64d",T.mat[][i]);
printf("\n");
}
return ;
} /*
3 1 6
g 1
g 2
g 2
s 1 2
g 3
e 2
0 0 0
*/
加油!少年!!!
Training little cats(poj3735,矩阵快速幂)的更多相关文章
- poj 3735 Training little cats(矩阵快速幂,模版更权威,这题数据很坑)
题目 矩阵快速幂,这里的模版就是计算A^n的,A为矩阵. 之前的矩阵快速幂貌似还是个更通用一些. 下面的题目解释来自 我只想做一个努力的人 @@@请注意 ,单位矩阵最初构造 行和列都要是(猫咪数+1) ...
- POJ 3735 Training little cats(矩阵快速幂)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11787 Accepted: 2892 ...
- 2014 Super Training #10 G Nostop --矩阵快速幂
原题: FZU 2173 http://acm.fzu.edu.cn/problem.php?pid=2173 一开始看到这个题毫无头绪,根本没想到是矩阵快速幂,其实看见k那么大,就应该想到用快速幂什 ...
- 矩阵快速幂 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 矩阵快速幂+稀疏矩阵乘法优化
题目链接 题意:有n个猫,开始的时候每个猫都没有坚果,进行k次操作,g x表示给第x个猫一个坚果,e x表示第x个猫吃掉所有坚果,s x y表示第x个猫和第y个猫交换所有坚果,将k次操作重复进行m轮, ...
- [poj3735] Training little cats_矩乘快速幂
Training little cats poj-3735 题目大意:给你n个数,k个操作,将所有操作重复m次. 注释:三种操作,将第i个盒子+1,交换两个盒子中的个数,将一个盒子清空.$1\le m ...
- Training little cats_矩阵快速幂
Description Facer's pet cat just gave birth to a brood of little cats. Having considered the health ...
- POJ3735【矩阵快速幂】
逛了一圈...觉得这篇讲的比较清楚:传送门~ 简要概括: 1.线性代数的知识,单位矩阵的利用:(如果不知道单位矩阵的,先去补习一下线代,做几题行列式就会了): 2.然后构造好矩阵以后,直接做M次乘积运 ...
- Training little cats poj3735
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9299 Accepted: 2 ...
随机推荐
- Unity相机跟随-----根据速度设置偏移量
这里假设在水中的船,船有惯性,在不添加前进动力的情况下会继续移动,但是船身是可以360度自由旋转,当船的运动速度在船的前方的时候,相机会根据向前的速度的大小,设置相机的偏移量,从而提高游戏的动态带感. ...
- openvSwitch tunnel
ovs tunnel 实验拓扑 实验拓扑搭建基础脚本 #vbox虚拟机1 ip netns add left ip link add name veth1 type veth peer name sw ...
- 用.NET WebService Studio调试Web Service解决SOAPAction的问题
话说是这样的,这两天开发一个短信发送功能,客户给了一个 Web Service 地址(没有文档),让我调用就可以发送了, 我在VS 2013添加了服务引用,一切正常,可是执行代理方法时,怎么都报错 R ...
- isBalanced函数实现
原文:从一道面试题谈起,作者:360奇舞团 刘观宇 题目: 创建一个函数来判断给定的表达式中的大括号是否闭合,返回 true/false,对于空字符串,返回 true var expression = ...
- flask-Datatables
我先给大家推荐一个jQuery开源库网址 http://www.jq22.com/ Datatables 是一款jquery表格插件.他是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能 ...
- shopify网站转化率优化之结账页checkout优化
昨天分享了“利用GOOGLE地图API实现shopify结账页checkout地址自动填写地址字段”是个非常屌的功能,但shopify默认的结账页checkout是这样的如图 [caption id= ...
- 【learning】 扩展lucas定理
首先说下啥是lucas定理: $\binom n m \equiv \binom {n\%P} {m\%P} \times \binom{n/P}{m/P} \pmod P$ 借助这个定理,求$\bi ...
- 【learning】 扩展欧几里得算法(扩展gcd)和乘法逆元
有这样的问题: 给你两个整数数$(a,b)$,问你整数$x$和$y$分别取多少时,有$ax+by=gcd(x,y)$,其中$gcd(x,y)$表示$x$和$y$的最大公约数. 数据范围$a,b≤10^ ...
- iframe 跨域调用父级方法的方案
一.如果高层域名相同的话,可以通过document.domain来实现跨域访问 例如: 父级域名:localhost:8080 子级域名:localhost:9090 那么可以设置document.d ...
- 课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 3、Python Basics with numpy (optional)
Python Basics with numpy (optional)Welcome to your first (Optional) programming exercise of the deep ...