hdu 4291 A Short problem (矩阵快速幂+循环节)
2015-08-26 11:21
435 查看
[align=left]Problem Description[/align]
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
[align=left]Input[/align]
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).
[align=left]Output[/align]
For each test case, please print a single line with a integer, the corresponding answer to this case.
[align=left]Sample Input[/align]
0
1
2
[align=left]Sample Output[/align]
0
1
42837
这题主要找循环节,mo1=1000000007,mo2=222222224,mo3=183120;找到循环节后只要用矩阵快速幂就可以了,下面有找循环节代码。
由于找循环节很耗时,所以找到后直接写出来,不用写在代码里。
找循环节:
View Code
ac代码:
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
[align=left]Input[/align]
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).
[align=left]Output[/align]
For each test case, please print a single line with a integer, the corresponding answer to this case.
[align=left]Sample Input[/align]
0
1
2
[align=left]Sample Output[/align]
0
1
42837
这题主要找循环节,mo1=1000000007,mo2=222222224,mo3=183120;找到循环节后只要用矩阵快速幂就可以了,下面有找循环节代码。
由于找循环节很耗时,所以找到后直接写出来,不用写在代码里。
找循环节:
#include<cstdio> long long mo1=1000000007; int main() { long long i=1,a=1,b=0,c; while (i) { c=(3*a+b)%mo1; b=a; a=c; if (a==1&&b==0) { printf("%I64d\n",i); break; } i++; } }
View Code
ac代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long mo1=1000000007; long long mo2=222222224; long long mo3=183120; long long s1[3][3],s2[3][3],s3[3][3]; long long f(long long n,long long mo) { int i,j,k; s1[0][0]=s2[0][0]=3; s1[0][1]=s2[0][1]=1; s1[1][0]=s2[1][0]=1; s1[1][1]=s2[1][1]=0; n-=2; while (n) { if (n&1) { memset(s3,0,sizeof(s3)); for (k=0;k<2;k++) for (i=0;i<2;i++){if (!s1[i][k]) continue; for (j=0;j<2;j++) s3[i][j]=(s3[i][j]+s1[i][k]*s2[k][j])%mo;} for (i=0;i<2;i++) for (j=0;j<2;j++) s2[i][j]=s3[i][j]; } memset(s3,0,sizeof(s3)); for (k=0;k<2;k++) for (i=0;i<2;i++) {if (!s1[i][k]) continue; for (j=0;j<2;j++) s3[i][j]=(s3[i][j]+s1[i][k]*s1[k][j])%mo;} for (i=0;i<2;i++) for (j=0;j<2;j++) s1[i][j]=s3[i][j]; n>>=1; } return s2[0][0]; } int main() { long long n; long long ans; while (~scanf("%I64d",&n)) { if (n==0) {printf("0\n");continue;} if (n==1) {printf("1\n");continue;} ans=f(n,mo3); if (ans>=2) //一定要有,不然ans<2时函数就会死循环。 ans=f(ans,mo2); if (ans>=2) ans=f(ans,mo1); printf("%I64d\n",ans); } }
相关文章推荐
- Java中使用RSA对请求和接收数据进行签名校验
- 一句话菜刀获取ip详细信息
- Zend Studio常用配置
- SQL注入攻击常见类型及解决方案
- PS学习笔记-------仿制图章工具
- html+javascript实现可编辑表格
- sublimetext 破解码
- java内部类与匿名内部类作用是什么?
- python 元类
- ZooKeeper学习1---简单介绍
- magento上新产品,前台不显示不显示属性,后台却有属性问题
- can't access tty,job control turned off
- TCP协议疑难杂症全景解析
- PHP禁用缓存
- 解决:-1054932979 : OLAP 存储引擎中存在错误: 处理“MultidimensionalTest”数据库的“DIM产品”维度的“Id”属性时出错。
- 统治世界的十大算法
- Debian Linux系统如何进入单用户模式恢复密码
- hdu4288-Coder(2012 chengdu online)(暴力数组或vector或线段树)
- Hadoop之hdfs单机最简配置(Cent OS 7)
- 解析nginx负载均衡