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

1.题面

http://poj.org/problem?id=3735

2.题意

有n只小猫,给定关于这n只小猫的三种操作,以及由这k中操作组成的一个序列,将该序列代表的操作执行m次,m的量级为10的9次方,输出最后小猫的状态。

3.思路

将所有操作合并成一个操作矩阵,最后对该矩阵进行m次乘法,使用矩阵快速幂加速运算

4.代码

/*****************************************************************
  > File Name: cpp_acm.cpp
  > Author: Uncle_Sugar
  > Mail: [email protected]
  > Created Time: Fri 07 Oct 2016 14:29:37 CST
 *****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;

# define rep(i,a,b) for (i=a;i<=b;i++)
# define rrep(i,a,b) for (i=b;i>=a;i--)
# define mset(aim, val) memset(aim, val, sizeof(aim))

struct QuickIO{
	QuickIO(){const int SZ = 1<<20;
		setvbuf(stdin ,new char[SZ],_IOFBF,SZ);
		setvbuf(stdout,new char[SZ],_IOFBF,SZ);
	}				//*From programcaicai*//
}QIO;

template<class T>void PrintArray(T* first,T* last,char delim=' '){
	for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim);
}

/*
   1.see the size of the input data before you select your algorithm 
   2.cin&cout is not recommended in ACM/ICPC
   3.pay attention to the size you defined, for instance the size of edge is double the size of vertex
 */

const int debug = 1;
//# const int size  = 10 + ; 
const int INF = INT_MAX>>1;
typedef long long ll;

const int MatrixSize = 10 + 100; //矩阵大小,注意能小就小  

struct Matrix{  
	ll T[MatrixSize][MatrixSize], sz;  
	//# Matrix(){}
	Matrix(int _sz){
		init(_sz);
	}

	void init(int _sz){  
		sz = _sz;  
		memset(T, 0, sizeof(T));  
	}  

	void Diag(int v){
		for (int i = 1; i <= sz; i++){
			T[i][i] = v;
		}
	}

	Matrix operator * (const Matrix& oper)const{
		Matrix ret(sz);
		for (int i = 1; i <= sz; i++){
			for (int j = 1; j <= sz; j++){
				if (T[i][j] == 0) continue;
				for(int k = 1; k <= sz; k++){
					if (oper.T[j][k] == 0) continue;
					ret.T[i][k] += T[i][j]*oper.T[j][k];
				}
			}
		}
		return ret;
	}

	Matrix QuickPowerMod(ll b){
		Matrix ret(sz);
		Matrix t = *this;
		ret.Diag(1);
		while (b){
			if(b&1)
				ret = t*ret;
			t = t*t;
			b >>= 1;
		}
		return ret;
	}

	Matrix operator ^ (int n){
		Matrix ret(sz);
		ret.Diag(1);
		Matrix t = *this;
		while (n){
			if (n & 1)
				ret = t*ret;
			t = t*t;
			n >>= 1;
		}
		return ret;
	}

	void Print(){
		for (int i = 1; i <= sz; i++)
			PrintArray(T[i] + 1, T[i] + sz + 1);
		cout << "end" << endl;
	}
};  




int main()
{
	/*std::ios::sync_with_stdio(false);cin.tie(0);*/
	int n, m, k;
	while (scanf("%d%d%d", &n, &m, &k) != EOF){
		if (n==0 && m==0 && k==0) break;
		Matrix op(n+1);
		op.Diag(1);
		while (k--){
			char str[10];
			scanf("%s", str);
			if (str[0] == 'g'){
				int a;
				scanf("%d", &a);
				++a;
				op.T[1][a]++;
			}else if (str[0] == 's'){
				int a, b;
				scanf("%d%d", &a, &b);
				++a, ++b;
				for (int i = 1; i <= op.sz; i++) swap(op.T[i][a], op.T[i][b]);
			}else if (str[0] == 'e'){
				int a;
				scanf("%d", &a);
				a++;
				for (int i = 1; i <= op.sz; i++) op.T[i][a] = 0;
			}
		}
		//# op.Print();
		op = op^m;
		for (int i = 2; i <= n+1; i++){
			printf("%lld%c", op.T[1][i], i==n+1?'\n':' ');
		}
	}

	return 0;
}


猜你喜欢

转载自blog.csdn.net/sinat_29278271/article/details/52759758
今日推荐