【矩阵乘法】【快速幂】幼儿园数学题II

Description

这天,当一头雾水的LZH同学在考场上痛哭的时候,一旁的YMW早就如切菜一样cut掉了简单至极的第一题,风轻云淡的冲击着满分,然而最后一道题着实难道了他,毕竟是幼儿园副园长树皮和著名毒瘤秋彪为了防止人AK而出的,可是YMW作为ACrush的著名粉丝,向来以AK为目标,永不言败,而他能不能AK就看你了
题目是酱紫的,f(n)-f(3)-f(4)-f(5)-…-f(n-3)-f(n-2)=(n+4)(n-1)/2,f(1)=1,f(2)=1
求f(n)的前n项和

Input

输入 一个正整数n(保证0<=n<=2^31-1)

Output

输出 一个正整数,表示这个图形的整点个数,需要对1000000007求余

Sample Input
样例输入1
1
样例输入2
2
Sample Output
样例输出1
1
样例输出2
2

解题思路

f ( n ) − f ( 3 ) − f ( 4 ) − f ( 5 ) − . . . − f ( n − 3 ) − f ( n − 2 ) = ( n + 4 ) ( n − 1 ) / 2 f(n)-f(3)-f(4)-f(5)-...-f(n-3)-f(n-2)=(n+4)(n-1)/2 f(n)f(3)f(4)f(5)...f(n3)f(n2)=(n+4)(n1)/2

f ( n ) = ( n + 4 ) ( n − 1 ) / 2 + f ( 3 ) + f ( 4 ) + f ( 5 ) + . . . + f ( n − 3 ) + f ( n − 2 ) f(n) = (n+4)(n-1)/2 +f(3)+f(4)+f(5)+...+f(n-3)+f(n-2) f(n)=(n+4)(n1)/2+f(3)+f(4)+f(5)+...+f(n3)+f(n2)
f ( n ) = f(n) = f(n)= n 2 2 \frac{n^2}{2} 2n2 + 3 n 2 − 2 \frac{3n}{2}- 2 23n2 + f ( 3 ) + f ( 4 ) + f ( 5 ) + . . . +f(3)+f(4)+f(5)+... +f(3)+f(4)+f(5)+... + f ( n − 3 ) + f ( n − 2 ) +f(n-3)+f(n-2) +f(n3)+f(n2)

f ( n + 1 ) = ( n + 5 ) ( n ) / 2 + f ( 4 ) + f ( 5 ) + . . . + f ( n − 3 ) + f ( n − 2 ) + f ( n − 1 ) f(n+1) = (n+5)(n)/2 +f(4)+f(5)+...+f(n-3)+f(n-2)+f(n-1) f(n+1)=(n+5)(n)/2+f(4)+f(5)+...+f(n3)+f(n2)+f(n1)
f ( n + 1 ) = f(n+1) = f(n+1)= n 2 2 + 5 n 2 \frac{n^2}{2} + \frac{5n}{2} 2n2+25n + f ( 3 ) + f ( 4 ) + f ( 5 ) + . . . f ( n − 3 ) +f(3)+f(4)+f(5)+...f(n-3) +f(3)+f(4)+f(5)+...f(n3) + f ( n − 2 ) + f ( n − 1 ) +f(n-2)+f(n-1) +f(n2)+f(n1)

f ( n ) = > f ( n + 1 ) f(n)=>f(n+1) f(n)=>f(n+1)
f ( n + 1 ) = f ( n ) + 2 n 2 + 2 + f ( n − 1 ) = f ( n ) + ( n + 1 ) + 1 + f ( n − 1 ) f(n+1) = f(n) + \frac{2n}{2} +2+ f(n-1)=f(n) + (n+1)+1+f(n - 1) f(n+1)=f(n)+22n+2+f(n1)=f(n)+(n+1)+1+f(n1)
f ( n ) = f ( n − 2 ) + f ( n − 1 ) + n + 1 f(n) = f(n-2) + f(n - 1) + n + 1 f(n)=f(n2)+f(n1)+n+1

考虑1×5的矩阵 [ f [ n − 2 ] f [ n − 1 ] s [ n − 2 ] n 1 ] \begin{bmatrix} f[n-2]&f[n-1]&s[n-2]&n&1 \end{bmatrix} [f[n2]f[n1]s[n2]n1],
我们需要找到一个5×5的矩阵A,使得它乘以A得到如下1×5的矩阵:
[ f [ n − 1 ] f [ n ] s [ n − 1 ] n + 1 1 ] = [ f [ n − 1 ] f [ n − 1 ] + f [ n − 2 ] + n + 1 s [ n − 2 ] + f [ n − 1 ] n + 1 1 ] \begin{bmatrix} f[n-1]&f[n]&s[n-1]&n+1&1 \end{bmatrix}=\begin{bmatrix}f[n-1]&f[n-1]+f[n-2]+n+1&s[n-2]+f[n-1]&n+1&1\end{bmatrix} [f[n1]f[n]s[n1]n+11]=[f[n1]f[n1]+f[n2]+n+1s[n2]+f[n1]n+11]
容易构造出A为:
[ 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 ] \begin{bmatrix} 0& 1& 0& 0& 0\\ 1& 1& 1& 0& 0\\ 0& 0& 1& 0& 0\\ 0& 1& 0& 1& 0\\ 0& 1& 0& 1& 1 \end{bmatrix} 0100011011011000001100001


Code
#include <iostream>
#include <cstring>
#include <cstdio>
#define ll long long

using namespace std;

const ll Mod = 1000000007;
struct DT{
	int n, m;
	ll aed[10][10];
}A, B, Bc;
int n;

DT operator * (DT a, DT b){//矩阵乘法
	DT c;
	memset (c.aed, 0, sizeof (c.aed));
	c.n = a.n, c.m = b.m;
	for (int k = 1; k <= a.m; k++)
		for (int i = 1; i <= c.n; i++)
			for (int j = 1; j <= c.m; j++)
				c.aed[i][j] = (c.aed[i][j] + a.aed[i][k] * b.aed[k][j] % Mod) % Mod;
	return c;
}

void power (int x){//快速幂
	if (x == 1)
	{
		Bc = B;
		return; 
	}
	power (x / 2);
	Bc = Bc * Bc;
	if (x % 2)
		Bc = Bc * B;
}

void init (){//初始化
	A.n = 1, A.m = 5;
	A.aed[1][1] = A.aed[1][2] = A.aed[1][3] = A.aed[1][5] = 1, A.aed[1][4] = 3;//从f(3)开始初始化
	B.n = 5, B.m = 5;
	B.aed[1][2] = B.aed[2][1] = B.aed[2][2] = B.aed[2][3] = 1;
	B.aed[3][3] = B.aed[4][2] = B.aed[4][4] = 1;
	B.aed[5][2] = B.aed[5][4] = B.aed[5][5] = 1;
}

int main(){
	init();
	scanf ("%d", &n);
	if (n == 1)
		printf ("1");
	else
	{
		power (n - 1);
		A = A * Bc;
		printf("%lld", A.aed[1][3]);//A.aed[1][3]是s[n-2]的位置
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值