您的位置:首页 > 其它

poj 3420 Quad Tiling 【矩阵乘法】

2013-04-10 01:27 507 查看
http://poj.org/problem?id=3420

题目大意:求在一个4*N(N<=1000000000)的格子中放1*2的格子的方案数。

  首先推导出公式f(n)=f(n-1)+5f(n-2)+f(n-3)-f(n-4),然后将其用矩阵乘法进行优化。

  矩阵的转换看这里:http://www.cnblogs.com/aiiYuu/gallery/image/127131.html

  然后用矩阵连乘进行运算,将复杂度降到了O(logN)。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
const int N = 4;
int n , MOD;
struct Matrix {
int n , m;
int a

;
Matrix() {}
Matrix(int _n,int _m):n(_n),m(_m){};
void intput() {
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&a[i][j]);
}
Matrix operator + (const Matrix &b) {
Matrix tmp = Matrix(n,m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
tmp.a[i][j] = a[i][j] + b.a[i][j];
return tmp;
}
Matrix operator - (const Matrix &b) {
Matrix tmp = Matrix(n,m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
tmp.a[i][j] = a[i][j] - b.a[i][j];
return tmp;
}
Matrix operator * (const Matrix &b) {
Matrix tmp = Matrix(n,b.m);
for(int i=0;i<n;i++)
for(int j=0;j<b.m;j++)
tmp.a[i][j] = 0;
for(int i=0;i<n;i++)
for(int j=0;j<b.m;j++)
for(int k=0;k<m;k++) {
tmp.a[i][j] += a[i][k]*b.a[k][j];
tmp.a[i][j] %= MOD;
}
return tmp;
}
};

Matrix operator ^ (Matrix a , int p) {
Matrix ret = Matrix(a.n,a.m);
for(int i=0;i<a.n;i++)
for(int j=0;j<a.m;j++)
ret.a[i][j] = (i == j ? 1 : 0);
while(p) {
if(p%2) ret = ret * a;
a = a * a;
p /= 2;
}
return ret;
}
/*
Matrix mi(Matrix a , int p) {
Matrix tmp = Matrix(a.n,a.m);
for(int i=0;i<a.n;i++)
for(int j=0;j<a.m;j++)
if(i==j) tmp.a[i][j]=1;
else tmp.a[i][j]=0;
if(p == 0) return tmp;
if(p == 1) return a;
if(p % 2) tmp = a;
Matrix tt = mi(a , p/2);
return tt * tt * tmp;
}*/
Matrix A , h;
int main() {
while(~scanf("%d%d",&n,&MOD) && n+MOD) {
h = Matrix(4,4);
h.a[0][0]=1;
h.a[1][0]=5;
h.a[2][0]=11;
h.a[3][0]=36;
A = Matrix(4,4);
A.a[0][0]=0;A.a[0][1]=1;A.a[0][2]=0;A.a[0][3]=0;
A.a[1][0]=0;A.a[1][1]=0;A.a[1][2]=1;A.a[1][3]=0;
A.a[2][0]=0;A.a[2][1]=0;A.a[2][2]=0;A.a[2][3]=1;
A.a[3][0]=-1;A.a[3][1]=1;A.a[3][2]=5;A.a[3][3]=1;
A = A ^ (n-1);
A = A * h;
printf("%d\n" , A.a[0][0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: