POJ 3735 Training little cats 矩阵快速幂应用

点击打开链接

Training little cats

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 9807   Accepted: 2344

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

Source

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

有n只猫,一共有三种操作分别是:

g x 让第x只猫得到一个花生

e x 让第x只猫吃掉所有的花生

s x y  将第x只猫和第y只猫的花生数换一换

对于这些操作一共有k次,成为一整套。

重复这一整套操作m次,问最后每只猫有多少花生米。

巧妙的转换为矩阵相乘来操作。

设一个(n+1)*(n+1)

的矩阵,每一列代表一只猫,最后一行代表猫的花生米的个数。如果g操作则将最后一行+1,如果e操作,则将这一列置零,如果是s操作,则将x列和y列进行交换。这样就得到这样一个矩阵:

{                               }

{        A             B     }

{                               }

{                               }

{        C              D   }

这四部分当中A是由0,1构成的稀疏矩阵,B是最后一列 (除了最后一个元素) 并且全由0构成,C是最后一行 (除了最后一个元素) 代表每只猫的花生米数,D只有一个元素是1.

因为iM太大,即使是矩阵快速幂也会超时,因此可以对于稀疏矩阵进行优化。

对于稀疏矩阵可以这么计算:

for(int i=0;i<=n;i++)

for(int k=0;k<=n;k++)

if(a.m[i][k])

for(int j=0;j<=n;j++)

c.m[i][j]+=a.m[i][k]*b.m[k][j];

这样的话就可以愉快的在oj上跑200多MS。

//1768K	235MS
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn 127
#define ll long long
using namespace std;
ll n,m,k;
struct Matrax
{
    ll m[maxn][maxn];
    void clear(){memset(m,0,sizeof(m));}
}a,per;
void init()//建立矩阵
{
    a.clear();
    per.clear();
    char s[2];
    ll x,b;
    for(int i=0;i<=n;i++)
        {a.m[i][i]=1;per.m[i][i]=1;}
    for(ll j=0;j<k;j++)
    {
        scanf("%s",s);
        if(s[0]=='g')
        {
            scanf("%I64d",&x);
            a.m[n][x-1]++;
        }
        if(s[0]=='e')
        {
            scanf("%I64d",&x);
            for(int i=0;i<=n;i++)
                a.m[i][x-1]=0;
        }
        if(s[0]=='s')
        {
            scanf("%I64d%I64d",&x,&b);
            for(ll i=0;i<=n;i++)
                swap(a.m[i][x-1],a.m[i][b-1]);
        }
    }
}
Matrax multi(Matrax a,Matrax b)//矩阵相乘
{
    Matrax c;
    c.clear();
    for(int i=0;i<=n;i++)
        for(int k=0;k<=n;k++)
        if(a.m[i][k])
            for(int j=0;j<=n;j++)
                c.m[i][j]+=a.m[i][k]*b.m[k][j];
    return c;
}
Matrax power(ll k)//矩阵快速幂
{
    Matrax p,ans=per;
    p=a;
    while(k)
    {
        if(k&1){ans=multi(ans,p);k--;}
        else {k/=2;p=multi(p,p);}
    }
    return ans;
}
int main()
{
    while(scanf("%I64d%I64d%I64d",&n,&m,&k),n|m|k)
    {
        init();
        Matrax ans=power(m);
        for(int i=0;i<n-1;i++)
            printf("%I64d ",ans.m[n][i]);
        printf("%I64d\n",ans.m[n][n-1]);
    }
    return 0;
}

POJ 3735 Training little cats 矩阵快速幂应用

时间: 2024-10-10 20:10:27

POJ 3735 Training little cats 矩阵快速幂应用的相关文章

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

Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10593   Accepted: 2532 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

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

题目链接 题意:有n个猫,开始的时候每个猫都没有坚果,进行k次操作,g x表示给第x个猫一个坚果,e x表示第x个猫吃掉所有坚果,s x y表示第x个猫和第y个猫交换所有坚果,将k次操作重复进行m轮,问最后这n个猫各自有多少坚果. 题解:构造(n+1)*(n+1)的单位矩阵,data[i][j]表示第i个猫与第j个猫进行交换,最后一列的前n项就是每个猫的坚果数目,s操作就交换对应行,矩阵快速幂时间复杂度O(n^3*log2(m))会超时,我们注意到在n*n的范围内每一行只有一个1,利用稀疏矩阵的

poj 3735 Training little cats矩阵快速幂

Training little cats 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. H

poj 3735 Training little cats 矩阵

假设n=3 构造矩阵[1,0,0,0] 对于g 1操作,构造矩阵(0行i列++) 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 对于e 1操作,构造矩阵 (i整列清空) 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 对于s 1 2操作,构造矩阵 (i,j整列交换) 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 将k次操作依次按上述构造矩阵,得到一个轮回的转置矩阵.做m次快速幂就行了. 最坑的地方在于,答案要用longlong存,而longlo

矩阵快速幂 POJ 3735 Training little cats

题目传送门 1 /* 2 题意:k次操作,g:i猫+1, e:i猫eat,s:swap 3 矩阵快速幂:写个转置矩阵,将k次操作写在第0行,定义A = {1,0, 0, 0...}除了第一个外其他是猫的初始值 4 自己讲太麻烦了,网上有人讲的很清楚,膜拜之 5 详细解释:http://www.cppblog.com/y346491470/articles/157284.html 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #inc

poj 3735 Training little cats(矩阵快速幂)

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 t

[POJ 3735] Training little cats (构造矩阵、矩阵快速幂)

Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9613   Accepted: 2296 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 th

poj 3735 Training little cats(构造矩阵)

http://poj.org/problem?id=3735 大致题意: 有n只猫,开始时每只猫有花生0颗,现有一组操作,由下面三个中的k个操作组成: 1. g i 给i只猫一颗花生米 2. e i 让第i只猫吃掉它拥有的所有花生米 3. s i j 将猫i与猫j的拥有的花生米交换 现将上述一组操作循环m次后,问每只猫有多少颗花生? 再一次感受到了矩阵的强大...循环m次,且m这么大,很容易想到构造转换矩阵,但如何构造是个问题.尤其是第一种操作,第i只猫增加一个花生.具体构造方法是把矩阵扩大为(

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