3.无聊的游戏(boring.pas/c/cpp)
【题目描述】
有一个很无聊的游戏,就是——根据递推公式计算数列
没错,这道题就是这么无聊!
给你数列f(0)=1, f(n)=f(n-1)^2+1 (n > 0)
求出f(n)
(既然题目已经这么无聊了,那就不让大家写高精度了,取个模好了)
【输入格式】
一个整数n
【输出格式】
一行一个整数f(n),结果对1200007取模
【样例输入】
3
【样例输出】
26
【数据规模】
10%数据 1<=n<=10
30%数据 1<=n<=10^6
100%数据 1<=n<=10^9
【时限】
1s
①如果你直接按题目暴力能拿30分
②遇到这种按公式,并且是由前一个推当前的(即由f[i-1]推f[i]的)那么就可以想到打表!这个也能得100分
不过由于数据太庞大,就只能部分打表(即每隔100w打一个数,然后写到你自己程序的数组里),完了后就该写自己的程序了,直接用n/100w找到是哪个循环节,然后只需向后推n%100w次即可,这样最坏的情况也就是退了100w次!很轻松就过了
③不过要想代码简洁点,也要用到上面的打表,然后写一个程序找到循环节,也能得100分
这个打表出来了,你想凭肉眼看出循环节,可能不大现实(除非你是神牛。。。),所以还需要借助程序,在写一个程序,把刚才的表当做输入文件,每读一个数,就hash标记一下,后面只要遇到一个已经标记的数,那么这之间必定是循环的!
具体的打表我会在后面写一个打表专题,只需在标签那里找到“打表”即可
这里我已经找出来循环节:从803开始循环,570为一个周期
C++ Code
#include
using namespace std;
const int mod=1200007;
int n;
long long f[1500];
int main()
{
freopen("boring.in","r",stdin);
freopen("boring.out","w",stdout);
cin>>n;
int i;
f[0]=1;
for(i=1;i<=1500;i++)
{
f[i]=((f[i-1]*f[i-1])%mod+1)%mod;
if(i==n)
{
cout<