F(N)---hdu2802(寻找循环节)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2802

f[1] = 1;

f[2] = 7;

f[n] = (f[n-2] - (n-1)*(n-1)*(n-1)+ n*n*n) % 2009, n>2;

给你一个n让你输出f[n];(n<1e9)由于n较大,所以不能直接输出,结果是对2009求余所以一定存在循环节,由于 f(n) 只与 f(n-2) 和 n 有关,

所以我们只需判断 G[n][f[n-2]] 第一次出现和第二次出现的次数即可,差值就是循环节;

#include <stdio.h>
#include <algorithm>
#include<string.h>
#include<queue>
using namespace std;

#define met(a, b) memset(a, b, sizeof(a))
#define MOD 1000000007
#define N 2010
#define INF 0x3f3f3f3f

typedef long long LL;

const int maxn = 2100;

int G[maxn][maxn], F[maxn*maxn] = {0,1,7,20};

int main()
{
    int k = 1, n;
    G[3][1] = k++;

    for(int i=4; i<maxn*maxn; i++)
    {
        F[i] = (F[i-2]-(i-1)*(i-1)*(i-1) + i*i*i)%2009;

        if(G[i%2009][F[i-2]])///说明n和f[n-2]对应的已经出现过了,说明存在循环节
        {
            /// printf("%d %d
", G[i%2009][F[i-2]], k);
            break;
        }

        G[i%2009][F[i-2]] = k++;
    }

    while(scanf("%d", &n), n)
    {
        printf("%d
", F[n%4018]);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5340510.html