您的位置:首页 > 其它

CodeForces 185A Plant 矩阵快速幂

2014-09-17 18:52 169 查看
题意:最开始给你一个正三角形,每一步,一个正三角形可以变成三个正三角形和一个反三角形,而一个反三角形可以构成一个正三角形和三个反三角形,问额你n步之后一共有多少个正三角形。

解题思路:因为n太大,有10^18这么大,所以我们只能用矩阵快速幂来求。

中间矩阵为

3 1

1 3

初始矩阵为

0 (负)

1 (正)

解题代码:

// File Name: temp.cpp
// Author: darkdream
// Created Time: 2014年09月17日 星期三 11时35分45秒

#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
#define LL long long
#define m 1000000007
using namespace std;
int n ;
struct Matrix
{
LL mat[20][20];
void clear()
{
memset(mat,0,sizeof(mat));
}
void output()
{
for(int i =0  ;i < n ;i ++)
{
for(int j = 0 ;j < n ;j ++)
printf("%I64d ",mat[i][j]);
printf("\n");
}
}
void init()
{
n = 2;
clear();
mat[0][0] = 3;
mat[0][1] = 1;
mat[1][0] = 1;
mat[1][1] = 3;
}
Matrix operator *(const Matrix &b) const
{
Matrix ret;
ret.clear();
for(int i = 0 ;i < n ;i ++)
for(int j = 0;j < n;j ++)
{
for(int k = 0 ;k < n ;k ++)
{
ret.mat[i][j] =(ret.mat[i][j] + mat[i][k] * b.mat[k][j]) % m ; // 第I 行  第J  列
}
}
return ret;
}
};
Matrix Pow( Matrix a ,LL t )
{
Matrix ret;
ret.clear();
for(int i = 0 ;i < n ;i ++)
ret.mat[i][i] = 1;
Matrix tmp = a;
while(t)
{
if(t&1) ret = ret * tmp;
tmp = tmp * tmp;
t >>=1;
}
return ret;
}
int main(){
LL l ;
while(scanf("%I64d",&l) != EOF)
{
if(l == 0)
{
printf("1\n");
continue;
}
Matrix  a;
a.init();
a = Pow(a,l);
printf("%I64d\n",a.mat[1][1]);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: