HDU 4291 A Short problem 第37届ACM/ICPC 成都赛区网络赛1004题 (找规律,取模求循环节)
A Short problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 344 Accepted Submission(s): 131
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
0 1 2
Sample Output
0 1 42837
Source
Recommend
liuyiding
这么水的题目比赛时竟然没有做出来。。。
惭愧啊!!!!
其实只要是取模都可以找到循环节的。
第一次是MOD=1000000007 找出循环节是222222224
第二次是MOD=222222224,找出循环节183120
第二次是MOD=222222224,找出循环节183120
找循环节暴力找就可以了,矩阵乘法找循环节更加慢。
附上找循环节程序:
View Code
#include<stdio.h> const long long MOD=222222224;//第一次是MOD=1000000007 找出循环节是222222224 //第二次是MOD=222222224,找出循环节183120 int main() { long long a,b; a=1; b=3; for(int i=1;;i++) { if(a==0&&b==1) { printf("%d\n",i); break; } long long c=3*b+a; c%=MOD; a=b; b=c; } return 0; }
下面是程序。
//1004 #include<stdio.h> #include<iostream> #include<map> #include<set> #include<algorithm> #include<string.h> #include<stdlib.h> using namespace std; const long long MOD=1000000007; const long long MOD2=222222224; const long long MOD3=183120; const int MAXN=10; struct Matrix { long long mat[MAXN][MAXN]; int n,m; }; Matrix mul(Matrix a,Matrix b,long long m) { Matrix ret; ret.n=a.n; ret.m=b.m; for(int i=0;i<a.n;i++) for(int j=0;j<b.m;j++) { ret.mat[i][j]=0; for(int k=0;k<a.m;k++) { ret.mat[i][j]+=(a.mat[i][k]*b.mat[k][j]%m); ret.mat[i][j]%=m; } } return ret; } Matrix pow(Matrix a,long long n,long long m) { if(n==1)return a; Matrix ret=a; Matrix temp=a; for(int i=0;i<a.n;i++) for(int j=0;j<a.n;j++) { if(i==j)ret.mat[i][j]=1; else ret.mat[i][j]=0; } while(n) { if(n&1)ret=mul(ret,temp,m); temp=mul(temp,temp,m); n>>=1; } return ret; } int main() { //freopen("D.in","r",stdin); // freopen("D.out","w",stdout); Matrix A; A.n=A.m=2; A.mat[0][0]=3; A.mat[0][1]=1; A.mat[1][0]=1; A.mat[1][1]=0; Matrix f0; f0.n=2; f0.m=1; f0.mat[0][0]=1; f0.mat[1][0]=0; long long n; Matrix tmp; Matrix temp; while(scanf("%I64d\n",&n)!=EOF) { temp=pow(A,n,MOD3); tmp=mul(temp,f0,MOD3); long long tt=tmp.mat[1][0]; temp=pow(A,tt,MOD2); tmp=mul(temp,f0,MOD2); tt=tmp.mat[1][0]; temp=pow(A,tt,MOD); tmp=mul(temp,f0,MOD); tt=tmp.mat[1][0]; printf("%I64d\n",tt); } return 0; }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想