佳佳的 Fibonacci
// 佳佳的 Fibonacci.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
* http://ybt.ssoier.cn:8088/problem_show.php?pid=1644
*
* https://loj.ac/p/10222
佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用 S(n) 表示 Fibonacci 前 n 项和 modm 的值,
即 S(n)=(F1+F2+...+Fn)modm,其中 F1=F2=1,Fi=Fi−1+Fi−2 。可这对佳佳来说还是小菜一碟。
终于,她找到了一个自己解决不了的问题。用 T(n)=(F1+2F2+3F3+...+nFn)modm 表示 Fibonacci 数列前 n 项变形后的和 modm 的值。
现在佳佳告诉你了一个 n 和 m,请求出 T(n) 的值。
【输入】
输入数据包括一行,两个用空格隔开的整数 n,m。
【输出】
仅一行,T(n) 的值。
【输入样例】
5 5
【输出样例】
1
【提示】
样例解释
T(5)=(1+2×1+3×2+4×3+5×5)mod5=1
数据范围与提示:
对于 30% 的数据,1≤n≤1000;
对于 60% 的数据,1≤m≤1000;
对于 100% 的数据,1≤n,m≤231−1。
*/
#include <iostream>
#include <cstring>
using namespace std;
const int N = 4;
int n, m;
void mul(int res[][N], int a[][N], int b[][N]) {
static int temp[N][N]; memset(temp, 0, sizeof temp);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
temp[i][j] = temp[i][j] + 1LL*a[i][k] * b[k][j] % m;
temp[i][j] %= m;
}
}
}
memcpy(res, temp, sizeof temp);
}
int main()
{
int f[N][N] = { 1,1,1,0 };
int a[N][N] = {
{0,1,0,0},
{1,1,1,0},
{0,0,1,1},
{0,0,0,1}
};
cin >> n >> m;
int cpn = n;
n--;
while (n) {
if (n & 1) mul(f, f, a);
mul(a, a, a);
n >>= 1;
}
cout << (1ll* cpn * f[0][2]%m - f[0][3]+m)%m << endl;
return 0;
}
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
浙公网安备 33010602011771号