您的位置:首页 > 理论基础 > 计算机网络

HDU 4291 A Short problem 第37届ACM/ICPC 成都赛区网络赛1004题 (找规律,取模求循环节)

2012-09-17 15:48 435 查看

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


[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

[align=left]Source[/align]
2012 ACM/ICPC Asia Regional Chengdu Online

[align=left]Recommend[/align]
liuyiding

这么水的题目比赛时竟然没有做出来。。。
惭愧啊!!!!
其实只要是取模都可以找到循环节的。
第一次是MOD=1000000007 找出循环节是222222224
第二次是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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐