首页 > 代码库 > 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): 1716 Accepted Submission(s): 631
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
此题出得比较精妙,
分析:假设g(g(g(n)))=g(x),x可能超出范围,但是由于mod 10^9+7,所以可以求出x的循环节View Code
求出x的循环节后,假设g(g(g(n)))=g(x)=g(g(y)),即x=g(y),y也可能非常大,但是由x的循环节可以求出y的循环节
如何求循环节点:
1 /*采用事先处理自己可以求出来*/ 2 LL work(LL mod){ 3 LL a=0,b=1; 4 for(LL i=2;;++i) 5 { 6 a=(b*3+a)%mod; 7 a=a^b; 8 b=a^b; 9 a=a^b;10 if(a == 0 && b == 1) return i;11 }
所以依次将mod1带入得到mod2=222222224;
然后将mod2带入得到mod3=183120;
然后就是快速矩阵了。
代码:
1 //#define LOCAL 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #define LL __int64 6 using namespace std; 7 const int mod1 =1000000007; 8 const int mod2=222222224; 9 const int mod3=183120;10 11 LL mat[2][2];12 LL ans[2][2];13 LL n;14 15 void Matrix(LL a[][2],LL b[][2],LL mod)16 {17 LL cc[2][2]={0};18 for(int i=0;i<2;i++)19 {20 for(int j=0;j<2;j++)21 {22 for(int k=0;k<2;k++)23 {24 cc[i][j]=(cc[i][j]+a[i][k]*b[k][j])%mod;25 }26 }27 }28 for(int i=0;i<2;i++)29 {30 for(int j=0;j<2;j++)31 {32 a[i][j]=cc[i][j];33 }34 }35 }36 37 void pow(LL w,LL mod)38 {39 while(w>0)40 {41 if(w&1) Matrix(ans,mat,mod);42 w>>=1;43 if(w==0)break;44 Matrix(mat,mat,mod);45 }46 }47 void input(LL w,LL mod)48 {49 mat[0][0]=3;50 mat[0][1]=mat[1][0]=1;51 mat[1][1]=0;52 ans[0][0]=ans[1][1]=1;53 ans[0][1]=ans[1][0]=0;54 pow(w,mod);55 // printf("%I64d\n",ans[0][0]);56 }57 void work(int i,__int64 w)58 {59 if(i==4||w==0||w==1)60 {61 if(w==0)62 printf("0\n");63 else if(w==1)64 printf("1\n");65 else66 printf("%I64d\n",ans[0][0]);67 return ;68 }69 LL mod;70 if(i==1)mod=mod3;71 else if(i==2)mod=mod2;72 else if(i==3)mod=mod1;73 input(w-1,mod);74 work(i+1,ans[0][0]);75 }76 int main()77 {78 #ifdef LOCAL79 freopen("test.in","r",stdin);80 #endif81 while(scanf("%I64d",&n)!=EOF)82 work(1,n);83 return 0;84 }
HDU----(4291)A Short problem(快速矩阵幂)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。