/*
类似fib数列,矩阵相乘,取模,所以肯定会出现循环节,不知道为什么一定是从0、1开始循环的
*/
//求循环节
#include <cstdio>
#include <set>
const __int64 M = 222222224;
using namespace std;
__int64 a[4], b[4];
int main()
{
set<__int64> se;
__int64 i;
__int64 f1 = 1, f0 = 0;
for(i = 2; ; ++ i)
{
__int64 f2 = (3 * f1 + f0) % M;
if(f1 == 0 && f2 == 1) break;
f0 = f1; f1 = f2;
}
printf("%I64d\n", i - 1);
return 0;
}
//222222224
//183120
//主程序
#include <cstdio>
#include <set>
const __int64 M0 = 1000000007;
const __int64 M1 = 222222224;
const __int64 M2 = 183120;
using namespace std;
__int64 a[4], b[4];
//其中a[0]的值为fid(n+1)
__int64 f(__int64 n, __int64 M)
{
if(1 == n)
{
a[0] = 3;
a[1] = a[2] = 1;
a[3] = 0;
return a[0];
}
f(n / 2, M);
b[0] = a[0] * a[0] + a[1] * a[2];
b[1] = a[0] * a[1] + a[1] * a[3];
b[2] = a[2] * a[0] + a[3] * a[2];
b[3] = a[2] * a[1] + a[3] * a[3];
a[0] = b[0] % M;
a[1] = b[1] % M;
a[2] = b[2] % M;
a[3] = b[3] % M;
if(n & 1)//当n为奇数时
{
b[0] = 3 * a[0] + a[2];
b[1] = 3 * a[1] + a[3];//a[0];
b[2] = a[0];//a[2] + a[3];
b[3] = a[1];
a[0] = b[0] % M;
a[1] = b[1] % M;
a[2] = b[2] % M;
a[3] = b[3] % M;
}
return a[0];
}
__int64 g(__int64 n, __int64 M)
{
if(n < 2)
return n;
else
return f(n - 1, M);
}
int main()
{
__int64 n;
while(scanf("%I64d", &n) != EOF)
{
printf("%I64d\n", g(g(g(n, M2), M1), M0) );
}
return 0;
}
//222222224
//183120
HDOJ 4291 A Short problem(Fib矩阵相乘)
最新推荐文章于 2018-08-02 11:26:00 发布