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 nm 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,矩阵快速幂)的更多相关文章

  1. poj 3735 Training little cats(矩阵快速幂,模版更权威,这题数据很坑)

    题目 矩阵快速幂,这里的模版就是计算A^n的,A为矩阵. 之前的矩阵快速幂貌似还是个更通用一些. 下面的题目解释来自 我只想做一个努力的人 @@@请注意 ,单位矩阵最初构造 行和列都要是(猫咪数+1) ...

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

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

  3. 2014 Super Training #10 G Nostop --矩阵快速幂

    原题: FZU 2173 http://acm.fzu.edu.cn/problem.php?pid=2173 一开始看到这个题毫无头绪,根本没想到是矩阵快速幂,其实看见k那么大,就应该想到用快速幂什 ...

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

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

  5. poj 3735 Training little cats 矩阵快速幂+稀疏矩阵乘法优化

    题目链接 题意:有n个猫,开始的时候每个猫都没有坚果,进行k次操作,g x表示给第x个猫一个坚果,e x表示第x个猫吃掉所有坚果,s x y表示第x个猫和第y个猫交换所有坚果,将k次操作重复进行m轮, ...

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

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

  7. Training little cats_矩阵快速幂

    Description Facer's pet cat just gave birth to a brood of little cats. Having considered the health ...

  8. POJ3735【矩阵快速幂】

    逛了一圈...觉得这篇讲的比较清楚:传送门~ 简要概括: 1.线性代数的知识,单位矩阵的利用:(如果不知道单位矩阵的,先去补习一下线代,做几题行列式就会了): 2.然后构造好矩阵以后,直接做M次乘积运 ...

  9. Training little cats poj3735

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

随机推荐

  1. powerviot open error in sharepoint 2013

    Testing Service c2WTS +- Service c2WTS found +- Service c2WTS is running +- Path of service: C:\Prog ...

  2. AJPFX平台:中国的经济是个大泡沫吗?这个泡沫即将崩解吗?

    AJPFX问:中国的经济是个大泡沫吗?这个泡沫即将崩解吗? 这一老问题,最近又一次引起世界的关注. 首先,中国在领导层变更之际,把2013年的增长目标定为7.5%,“保八”的调子不再,两位数高增长的时 ...

  3. JSOI2010 缓存交换

    题目链接:戳我 考虑一个贪心--就是每次我们都选择队列里面之后最晚加入的元素弹出. 维护一个nxt数组就行了. 特判一下之后不会再加入的元素. 代码如下: #include<iostream&g ...

  4. 网络编程-socket(三)(TCP长连接和UDP短连接、时间服务器)

    详解地址:https://www.cnblogs.com/mys6/p/10587673.html TCP server端 import socketsk = socket.socket() # 创建 ...

  5. vscode卡死问题

    网上有人说是和淘宝镜像冲突,也不知啥原因,接下来一下操作会好点: 文件->首选项->设置,搜索search.followSymlinks,把对勾去掉就行 1.修复vs code 造成 rg ...

  6. java 路径的问题

    在项目开发中会碰到各种各样的获取项目路径的一些问题: 1:java项目: 以获取  类路径下的mess.properties 为例来说明: 文件在项目中的位置: src/bz/beppe/demo/r ...

  7. 剑指offer九之变态跳台阶

    一.题目 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 二.思路 1.关于本题,前提是n个台阶会有一次n阶的跳法.分析如下: f(1) ...

  8. tensorflow学习总结之reduce_sum函数

    tensorflow里面集成了许多基于统计的数学函数,类似于reduce_sum,reduce_mean,reduce_min,reduce_max,等,根据字面意思分别是求和,求平均,求最大,求最小 ...

  9. [转]cximage双缓冲绘图 .

    1.起因 本来是想用gdi绘图的,但是一想到用gdi+libpng,还要自己处理一些比如alpha的效果之类的巨麻烦(而且涉及到处理每一个像素点的计算,一般都很耗时),我对自己处理像素点的能力一直持有 ...

  10. [原创]Entity Framework查询原理

    前言 Entity Framework的全称是ADO.NET Entity Framework,是微软开发的基于ADO.NET的ORM(Object/Relational Mapping)框架.Ent ...