#7157. 「微课 3.6.11 例 2」非水斐波那契数列
内存限制:256 MiB时间限制:1000 ms标准输入输出
题目类型:传统评测方式:文本比较
题目描述
给出一个正整数 ,求斐波那契数列的第 项对的值。(本题斐波那契数列的第一项为 。)
输入格式
一个正整数 。
输出格式
一个整数表示答案。
样例
样例输入复制
3
样例输出复制
2
数据范围与提示
对于 的数据,。
对于 的数据,。
对于所有数据,。
分类标签
题解(C++14):
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const ll SIZE = 5, mod = 1000000007;
inline ll read() {
ll x = 0, opr = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
opr = -opr;
ch = getchar();
}
while (ch >= '0' && ch <= '9') x = (x * 10) + (ch ^ 48), ch = getchar();
return x * opr;
}
struct matrix {
ll arr[SIZE][SIZE];
matrix() { memset(arr, 0, sizeof(arr)); }
inline void build() { arr[1][1] = arr[1][2] = arr[2][1] = arr[3][2] = 1; }
inline void build1() { arr[1][1] = arr[2][2] = arr[3][3] = 1; }
inline matrix operator*(matrix x) {
matrix res;
for (ll k = 1; k <= 3; k++)
for (ll i = 1; i <= 3; i++)
for (ll j = 1; j <= 3; j++)
res.arr[i][j] = (res.arr[i][j] + arr[i][k] * x.arr[k][j] % mod) % mod;
return res;
}
} num, ans;
ll N;
int main() {
N = read() - 1;
num.build();
ans.build1();
while (N) {
if (N & 1)
ans = ans * num;
num = num * num;
N >>= 1;
}
printf("%lld", ans.arr[1][1]);
return 0;
}
题解(C++ (NOI) ):
#include <bits/stdc++.h>
using namespace std;
#define maxn 101
#define mod 1000000007
#define ll long long
ll T, n;
struct matrix {
ll xnum, ynum;
ll p[maxn][maxn];
matrix() { memset(p, 0, sizeof(p)); }
inline void make() {
for (ll i = 1; i <= xnum; i++) p[i][i] = 1;
}
} a, b, ans;
matrix operator*(const matrix x, const matrix y) {
matrix z;
z.xnum = x.xnum;
z.ynum = y.ynum;
for (ll k = 1; k <= x.ynum; k++) {
for (ll i = 1; i <= z.xnum; i++) {
for (ll j = 1; j <= z.ynum; j++) {
z.p[i][j] += (x.p[i][k] * y.p[k][j]) % mod;
z.p[i][j] %= mod;
}
}
}
return z;
}
matrix ksm(matrix now, ll tim) {
if (tim == 0)
return b;
if (tim == 1)
return now;
matrix nowans = ksm(now, tim / 2);
if (tim % 2 == 0)
return nowans * nowans;
else
return now * nowans * nowans;
}
int main() {
a.xnum = 2;
a.ynum = 2;
a.p[1][1] = 1, a.p[1][2] = 1;
a.p[2][1] = 1, a.p[2][2] = 0;
b.xnum = 2;
b.ynum = 2;
b.make();
ans.xnum = 2;
ans.ynum = 1;
ans.p[1][1] = 1, ans.p[2][1] = 1;
cin >> n;
matrix nowans, nowans2;
nowans = ksm(a, n - 1);
nowans2 = nowans * ans;
cout << nowans2.p[2][1] << endl;
return 0;
}
题解(C++ 11(NOI) ):
#include <cstdio>
#define ll long long
struct node {
ll jz[3][3];
};
ll n, mod = 1000000007;
void che(node &x, node y) {
node js1 = x, js2 = y;
x.jz[1][1] = x.jz[1][2] = x.jz[2][1] = x.jz[2][2] = 0;
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
for (int k = 1; k <= 2; k++) x.jz[i][j] = (x.jz[i][j] + js1.jz[i][k] * js2.jz[k][j]) % mod;
}
ll pow(ll x) {
node ans, js;
ans.jz[1][1] = ans.jz[2][2] = 1, ans.jz[1][2] = ans.jz[2][1] = 0;
js.jz[1][1] = js.jz[1][2] = js.jz[2][1] = 1, js.jz[2][2] = 0;
while (x) {
if (x & 1)
che(ans, js);
che(js, js);
x >>= 1;
}
return (ans.jz[1][1] + ans.jz[1][2]) % mod;
}
int main() {
scanf("%lld", &n);
if (n <= 2)
return 0 * printf("1");
printf("%lld", pow(n - 2));
return 0;
}