首页 > 代码库 > HDU 4291 A Short problem(矩阵+循环节)
HDU 4291 A Short problem(矩阵+循环节)
A Short problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2711 Accepted Submission(s): 951
Problem Description
According to a research, VIM users tend to have shorter fingers, compared with Emacs users.
Hence they prefer problems short, too. Here is a short one:
Given n (1 <= n <= 1018), You should solve for
g(g(g(n))) mod 109 + 7
where
g(n) = 3g(n - 1) + g(n - 2)
g(1) = 1
g(0) = 0
Hence they prefer problems short, too. Here is a short one:
Given n (1 <= n <= 1018), You should solve for
where
Input
There are several test cases. For each test case there is an integer n in a single line.
Please process until EOF (End Of File).
Please process until EOF (End Of File).
Output
For each test case, please print a single line with a integer, the corresponding answer to this case.
Sample Input
012
Sample Output
0142837
Source
2012 ACM/ICPC Asia Regional Chengdu Online
/* * Author: lyucheng * Created Time: 2017年05月20日 星期六 16时40分42秒 * File Name: HDU-4291-A_Short_problem.cpp */ /* * 题意:让你求g(g(g(n)))mod 1e9+7,其中g(n)=3*g(n-1)+g(n-2) * * * 思路:g(n)可以通过矩阵快速幂求出来,但是干后分别求出各自的循环节,能得到第一个循环节是222222224, * 第二个循环节是183120 * */#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <stack>#include <queue>#include <set>#include <time.h>#define LL long long#define maxn 3 using namespace std;LL n;LL mod;/********************************矩阵快速幂**********************************/class Matrix { public: LL a[maxn][maxn]; void init() { memset(a,0,sizeof(a)); } Matrix operator +(Matrix b) { Matrix c; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) c.a[i][j] = (a[i][j] + b.a[i][j]) % mod; return c; } Matrix operator +(LL x) { Matrix c = *this; for (int i = 0; i < 2; i++) c.a[i][i] += x; return c; } Matrix operator *(Matrix b) { Matrix p; p.init(); for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) p.a[i][j] = (p.a[i][j] + (a[i][k]*b.a[k][j])%mod) % mod; return p; } Matrix power(LL t) { Matrix ans,p = *this; ans.init(); ans.a[0][0]=1; ans.a[1][1]=1; while (t) { if (t & 1) ans=ans*p; p = p*p; t >>= 1; } return ans; }}unit,init;/********************************矩阵快速幂**********************************/int main(int argc, char* argv[]){ // freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout; while(scanf("%lld",&n)!=EOF){ if(n<2){ printf("%lld\n",n); continue; } //首先求最里面的g(n) mod=183120; unit.init(); unit.a[0][0]=1,unit.a[0][1]=0,unit.a[1][0]=0,unit.a[1][1]=0; init.a[0][0]=3,init.a[0][1]=1,init.a[1][0]=1,init.a[1][1]=0; init=init.power(n-1); unit=unit*init; n=unit.a[0][0]; if(n>=2){//很重要,要不然当n<2的时候矩阵乘法就会死循环 mod=222222224; unit.init(); unit.a[0][0]=1,unit.a[0][1]=0,unit.a[1][0]=0,unit.a[1][1]=0; init.a[0][0]=3,init.a[0][1]=1,init.a[1][0]=1,init.a[1][1]=0; init=init.power(n-1); unit=unit*init; n=unit.a[0][0]; } if(n>=2){//很重要,要不然当n<2的时候矩阵乘法就会死循环 mod=1000000007; unit.init(); unit.a[0][0]=1,unit.a[0][1]=0,unit.a[1][0]=0,unit.a[1][1]=0; init.a[0][0]=3,init.a[0][1]=1,init.a[1][0]=1,init.a[1][1]=0; init=init.power(n-1); unit=unit*init; n=unit.a[0][0]; } printf("%lld\n",n); } return 0;}
HDU 4291 A Short problem(矩阵+循环节)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。