POJ 3735 矩阵乘法的小优化GET。
来源:互联网 发布:淘宝发布宝贝规则 编辑:程序博客网 时间:2024/06/12 21:39
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 integersn, m and k are given firstly, where n is the number of cats andk 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 6g 1g 2g 2s 1 2g 3e 20 0 0
Sample Output
2 0 1题目大意是:有n只开始木有花生吃的小猫,然后给你k个操作,而操作的情况有三种:g i表示第i只小猫得到一个花生 e i表示第i只小猫把花生全吃了, s i j表示第i只小猫 和第j只小猫交换花生个数,然后这k个操作执行m次,问最后各个小猫的花生个数。思路分析:额,很显然是矩阵快速幂了,构造矩阵是关键。。 这题老头子在我大一暑假就给我讲过,但是当时连快速幂是啥都不知道就不了了之了,后来又看到这道题就把它写 了,首先我们单独来看。对于第一种情况,得到一个花生的状态,额这个也算是本题唯一巧妙的地方吧,就是原本是n*n阶的矩阵增广为n+1*n+1阶的矩阵,为什么呢,因为我们不妨来看样例三只猫的情况如何对猫进行+1个花生的操作,我们可以想象有一只虚拟的猫有1个花生来提供,那么如果对于第一只猫获得一个花生我们可以构造如下矩阵:|1 0 0 0 | | 1 | | 1 ||1 1 0 0 |*| 0 |----->| 1 | 因此一般而言对于第i只猫获得一个花生只要在对应的n+1阶矩阵中的第i行第0列将0变成1即可。|0 0 1 0 | | 0 | | 0 ||0 0 0 1 | | 0 | | 0 |接下来是e操作,也就是表示第i只猫把花生全吃光,那么此时只要将初等矩阵中的第i行全部清零即可例如:|1 0 0 0 | | 1 | | 1 ||0 0 0 0 | | 1 | | 0 ||0 0 0 0 |* | 0 |------>| 0 | 表示第一只猫的花生吃光了|0 0 0 0 | | 0 | | 0 |最后是s操作,要求交换,实际上也就是交换第i和第j只猫咪的花生数,实际上也就是要把初等矩阵的第i j两行整体交换即可- -额好麻烦不举例子了接着就是进行k次操作,构造出base矩阵,然后去快速幂。。。一切貌似都按照计划很好的进行了,而且样例也过了。。 BUT 却T了八次。。。。为什么。。。 后面才发现是卡了矩阵乘法复杂度。。。一般而言矩阵乘法的朴素算法为O(n^3),但是我们发现在这个n+1阶矩阵中非零元素的个数至多为k个,所以是一个稀疏矩阵,因此可以对矩阵进行优化,当a[i][j]=0时就没必要进入循环再去乘了。。。这样可以将矩阵乘法予以一定的优化。。。 然后。。就过了。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;long long n,m,k;struct juzhen{long long m[105][105];};juzhen mut(juzhen a,juzhen b) { juzhen c; memset(c.m,0,sizeof(c.m)); for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { if(a.m[i][j]) for(int k=0;k<=n;k++) c.m[i][k]+=a.m[i][j]*b.m[j][k]; } } return c; }//稀疏矩阵的矩阵乘法juzhen pow(juzhen a,long long p){ juzhen ans; memset(ans.m,0,sizeof(ans.m)); for(int i=0;i<=n;i++) { ans.m[i][i]=1; } while(p) { if(p%2==0) { a=mut(a,a); p/=2; } else { ans=mut(ans,a); p--; } } return ans;}int main(){ while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF) { if(n==0&&m==0&&k==0) { return 0; } juzhen ans; memset(ans.m,0,sizeof(ans.m)); for(int i=0;i<=n;i++) { ans.m[i][i]=1; } while(k--) { long long x,y; char s[15]; scanf("%s",s); if(s[0]=='g') { scanf("%I64d",&x); ans.m[x][0]++; } else if(s[0]=='e') { scanf("%I64d",&x); for(int i=0;i<=n;i++) { ans.m[x][i]=0; } } else if(s[0]=='s') { scanf("%I64d%I64d",&x,&y); for(int i=0;i<=n;i++) { swap(ans.m[x][i],ans.m[y][i]); } } } if(m==0) { printf("0"); for(int i=2;i<=n;i++) { printf(" 0"); } printf("\n"); continue; } ans=pow(ans,m); printf("%I64d",ans.m[1][0]); for(int i=2;i<=n;i++) { printf(" %I64d",ans.m[i][0]); } printf("\n"); } return 0;}
- POJ 3735 矩阵乘法的小优化GET。
- [POJ 3735] Training little cats (矩阵幂+矩阵乘法的优化)
- 矩阵乘法的优化
- 矩阵乘法的优化
- 矩阵乘法的优化
- 矩阵乘法的优化
- POJ 3735 BNUOJ 3845 Training little cats 矩阵快速幂 稀疏矩阵乘法优化 计算机图形学的齐次坐标
- POJ 3213 PM3 矩阵乘法优化
- POJ 3213 矩阵乘法(优化)
- poj 3734 Blocks 矩阵乘法优化dp
- POJ-3735-Training little cats-构造矩阵+矩阵快速幂+稀疏矩阵乘法优化
- 矩阵乘法的常数优化
- POJ 3735 构造矩阵乘法
- 写的一个小的矩阵乘法
- 矩阵乘法的并行算法优化
- 矩阵乘法递推的优化艺术
- 【bzoj4547】【小奇的集合】【矩阵乘法】
- POJ - 3613 Floyd的思想+矩阵乘法
- git submodule 学习笔记(一)
- 提高mysql 批量插入和更新性能
- 【设计模式】策略模式
- Unix/Linux学习资料网站
- POJ-3635-Full Tank?
- POJ 3735 矩阵乘法的小优化GET。
- python类
- (未完成)上课笔记--管理信息系统
- 《Effective stl》——条款6的笔记
- oc 集合容器总结+扩展名的添加和获取
- 关于main(int argc,char **argv)中参数的说明
- VS2010运行速度优化汇总
- 华为Android手机打开Log, 显示日志
- QT拖拽功能