poj3735,,矩阵快速幂

Training little cats

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 9815   Accepted: 2346

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

Source

PKU Campus 2009 (POJ Monthly Contest – 2009.05.17), Facer

这题题意如下,有n 只猫咪,三种关于花生的命令 ( 得花生,吃花生,交换花生 ) ,给出一套命令,重复 n 次,问最后每只猫咪得到多少花生。

M那么大,毫无疑问,矩阵快速幂。

先构造一个单位矩阵,因为只需在单位矩阵上进行操作,然后用操作完之后得到的矩阵乘以初始的状态就得到最终的状态。

看下图:

第 i 只猫咪得花生就是在矩阵的第 i 行的最后一列加上1;

注意:如果是 n 只猫咪的话,要用n+1维的矩阵,即n+1维的方阵,多出来的一个才能起到操作的作用!

下面是重点,就是矩阵的快速幂,思路和整数的快速幂一样,不过该过程中会用稀疏矩阵出现,故可借此优化,

即跳过0元素;

我认为要注意的是:矩阵相乘时,需要借助另一个零矩阵,乘完之后再把结果放到该放的矩阵上,而不是直接把结果放到最终的矩阵上!

代码如下:

#include <stdio.h>
#include <string.h>
#include <math.h>
typedef __int64 int64;

int64 c[120][120],ans[120][120],d[120][120];

struct cat
{
	int64 p[120][120];
	cat(){memset(p,0,sizeof(p));}
};

int main()
{
	int64 i,j,m,n,k,x,y,t;
	char w[2];
	while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF )		//不能用while(scanf(----)!=EOF && n!=0 && m!=0 && k!=0)   这样其中一个为0就退出了
	{
		if(n==0 && m==0 && k==0)
			break;
		memset(ans,0,sizeof(ans));
		cat ca;
		for(i=0;i<=n;i++)
		{
			ca.p[i][i]=1;
			ans[i][i]=1;
		}
		for(i=0;i<k;i++)
		{
			scanf("%s",w);
			if(w[0]=='g')
			{
				scanf("%I64d",&x);
				ca.p[n][x-1]++;
			}
			else if(w[0]=='e')
			{
				scanf("%I64d",&x);
				for(j=0;j<=n;j++)
					ca.p[j][x-1]=0;
			}
			else
			{
				scanf("%I64d%I64d",&x,&y);
				for(j=0;j<=n;j++)
				{
					t=ca.p[j][x-1];
					ca.p[j][x-1]=ca.p[j][y-1];
					ca.p[j][y-1]=t;

				}
			}
		}

		while(m!=0)
		{
			if(m%2==1)
			{
				memset(d,0,sizeof(d));					//这里借助了零矩阵d;
				for(i=0;i<=n;i++)
					for(j=0;j<=n;j++)
						if(ca.p[i][j])
							for(k=0;k<=n;k++)
								d[i][k]+=ans[i][j]*ca.p[j][k];		//这里注意一下i,j,k的下标,别弄错了,体会一下
				for(i=0;i<=n;i++)
					for(j=0;j<=n;j++)
						ans[i][j]=d[i][j];				//再讲结果即矩阵d放到矩阵ans上,而不是直接把结果放到矩阵ans上
			}
			memset(c,0,sizeof(c));
			for(i=0;i<=n;i++)
					for(j=0;j<=n;j++)
					{
						if(ca.p[i][j]==0)
							continue;
						for(k=0;k<=n;k++)
							c[i][k]+=ca.p[i][j]*ca.p[j][k];
					}
			for(i=0;i<=n;i++)
				for(j=0;j<=n;j++)
					ca.p[i][j]=c[i][j];
			m=m/2;
		}

		for(i=0;i<n-1;i++)
			printf("%I64d ",ans[n][i]);
        printf("%I64d\n",ans[n][n-1]); 

	}
	return 0;
}

poj3735,,矩阵快速幂

时间: 2024-10-11 07:11:40

poj3735,,矩阵快速幂的相关文章

POJ3735 Training little cats DP,矩阵快速幂,稀疏矩阵优化

题目大意是,n只猫,有k个动作让它们去完成,并且重复m次,动作主要有三类gi,ei,s i j,分别代表第i只猫获得一个花生,第i只猫吃掉它自己所有的花生,第i只和第j只猫交换彼此的花生.k,n不超过100,m不超过1000,000,000,计算出最后每只猫还剩下多少个花生. 我们假设一个n维向量P,每个分量的值代表这n只猫所拥有的花生数,那么对于gi操作其实就是在第i维分量上加上1:对于ei,那就是在第i维分量上乘以0,说到这里,有木有感觉这很像3D坐标转化中的平移矩阵和缩放矩阵?没错,就是这

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 t

TZOJ--5480: 孤衾易暖 // POJ--3735 Training little cats (矩阵快速幂)

5480: 孤衾易暖 时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte 描述 哇,好难,我要放弃了(扶我起来,我还能A 寒夜纵长,孤衾易暖,钟鼓渐清圆. 生活也许有些不如意的地方,但是没有什么是拥有一只猫不能解决的,我最喜欢苏格兰折耳猫. 现在我有n只小猫,我要训练这些猫去满足我奇奇怪怪的需求. 就是要让他们去得到鱼,这样他们才会快乐.刚开始他们是没有鱼的 我对这些猫有3种训练要求: 第一种要求为get x,意为让第x只猫咪得到一条: 第二种要求为e

矩阵快速幂专题(三)

哈哈哈,博主又回来了!这次专题是第三弹也是最后一弹了,这次会对矩阵进行一个小收尾.做完这25道题,我感觉到其实我矩阵学得并不好,还有许多知识点没有学会.后面看情况可能还会继续开矩阵的专题,那应该是几个月以后的事了.从下周开始,应该会先学习一下数论的相关算法! 这次的七道题目(为什么题目越来越少了)主要是针对了矩阵的优化,对于会TLE的和MLE(内存爆了)的矩阵而且这个矩阵又恰好是同构矩阵(同构矩阵是啥?)的话,可以采用一维数组来模拟二维,从而降低复杂度.降低空间.(竟然是罕见的同时降时间和空间的

矩阵快速幂刷题系列

来源自http://blog.csdn.net/chenguolinblog/article/details/10309423 hdu 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5587    Accepted Submission(s): 4200 Problem Description A为一个方阵,则Tr

HDU 1757 A Simple Math Problem (矩阵快速幂)

[题目链接]:click here~~ [题目大意]: If x < 10 f(x) = x. If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 * f(x-10); 问f(k)%m的值. [思路]:矩阵快速幂,具体思路看代码吧,注意一些细节. 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分)

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define MAX_SIZE 30 #define CLR( a, b ) memset( a, b, sizeof(a) ) int MOD = 0; int n, k; st

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include