题意说的很清楚了,就不多说了。
打表找规律——ans[n] = F[n*2],其中F[i]为斐波那契数列数列第i项。
附代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int F[1001], C[1001]; void getF() { F[0] = 0, F[1] = 1; for(int i = 2; i <= 100; i++) F[i] = F[i-1] + F[i-2]; } void solve(int n, int m) { int ans = 0; C[0] = 1; for(int i = 1; i <= n; i++) { C[i] = C[i-1] * (n-i+1) / i; ans += C[i] * F[i] % m; } printf("%d\n", ans); } int main() { getF(); int t; int n, m; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); solve(n, m); } return 0; }
找到规律后,直接矩阵KO。
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> #define LL long long using namespace std; struct Matrix { LL a[2][2]; }; Matrix ori, res; LL F[2]; void init_Matrix() { memset(ori.a, 0, sizeof(ori.a)); memset(res.a, 0, sizeof(res.a)); res.a[0][0] = res.a[1][1] = 1; ori.a[0][1] = ori.a[1][0] = ori.a[1][1] = 1; } Matrix muitl(Matrix x, Matrix y, int m) { Matrix z; memset(z.a, 0, sizeof(z.a)); for(int i = 0; i < 2; i++) { for(int k = 0; k < 2; k++) { if(x.a[i][k] == 0) continue; for(int j = 0; j < 2; j++) z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j])%m) % m; } } return z; } void solve(int n, int m) { init_Matrix(); while(n) { if(n & 1) res = muitl(ori, res, m); ori = muitl(ori, ori, m); n >>= 1; } LL ans = res.a[1][1] % m; printf("%lld\n", ans); } int main() { F[0] = 0, F[1] = 1; int t, n, m; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); if(n == 0) { printf("0\n"); continue; } solve(n*2-1, m); } return 0; }