题目链接: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]] 第一次出现和第二次出现的次数即可,差值就是循环节;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }