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

D e s c r i p t i o n Description 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项和

I n p u t Input Input

输入 一个正整数n(保证 0 < = n < = 2 31 − 1 0<=n<=2^{31}-1 0<=n<=2311

O u t p u t Output Output

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

S a m p l e Sample Sample I n p u t Input Input#1
1
S a m p l e Sample Sample O u t p u t Output Output#1
1
S a m p l e Sample Sample I n p u t Input Input#2
2
S a m p l e Sample Sample O u t p u t Output Output#2
2

T r a i n Train Train o f of of T h o u g h t Thought Thought

我们来演算一下这个式子
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)=…+(n^2+3n-4)/2
f(n)=…+n^2/2+3n/2-2---------------②
由①得
f(n+1)=f(3)+f(4)+f(5)+…+f(n-3)+f(n-2)+f(n-1)+((n+1)+4)((n+1)-1)/2
f(n+1)=…+f(n-1)+((n+1)+4)((n+1)-1)/2
f(n+1)=…+f(n-1)+n(n+5)/2
f(n+1)=…+f(n-1)+(n^2+5n)/2
f(n+1)=…+f(n-1)+n^2/2+5n/2-----------------③
然后看③其实比②只多了f(n - 1) + (n ^ 2 / 2 + 5n / 2 - n ^ 2 / 2 - 3n / 2 + 2)
也就是f(n - 1) + n + 2
所以f(n + 1) = f(n) + f(n - 1) + n + 2
然后再变一下,把n+1变为n
f(n + 1) = f(n) + f(n - 1) + n + 2
f(n + 1) = f((n + 1) - 1) + f((n + 1) - 2) + (n + 1) + 1
f(n) = f(n - 1) + f(n - 2) + n + 1
然后就可以按常规矩阵乘法做了
ps
答案是算前缀和

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

const ll mod = 1000000007;

ll n;

struct wh_
{
    
    
	ll h[10][10];
}A, K;

wh_ operator *(wh_ a, wh_ b)
{
    
    
	wh_ c;
	memset(c.h, 0, sizeof(c.h));
	for(int i = 1; i <= 5; ++i)
		for(int j = 1; j <= 5; j++)
			for(int k = 1; k <= 5; k++)
				c.h[i][j] = (c.h[i][j] + a.h[i][k] * b.h[k][j] % mod) % mod;
	return c;
}

void power(ll m)
{
    
    
	while(m)
	{
    
    
		if(m & 1)K = K * A;
		A = A * A;
		m >>= 1;
	}
}

int main()
{
    
    
	scanf("%lld", &n);	
	A.h[1][1] = 0, A.h[1][2] = 1, A.h[1][3] = 0, A.h[1][4] = 0, A.h[1][5] = 0;
	A.h[2][1] = 1, A.h[2][2] = 1, A.h[2][3] = 0, A.h[2][4] = 0, A.h[2][5] = 1;
	A.h[3][1] = 0, A.h[3][2] = 1, A.h[3][3] = 1, A.h[3][4] = 0, A.h[3][5] = 0;
	A.h[4][1] = 0, A.h[4][2] = 1, A.h[4][3] = 1, A.h[4][4] = 1, A.h[4][5] = 0;
	A.h[5][1] = 0, A.h[5][2] = 0, A.h[5][3] = 0, A.h[5][4] = 0, A.h[5][5] = 1;
	K.h[1][1] = 1, K.h[1][2] = 1, K.h[1][3] = 3, K.h[1][4] = 1, K.h[1][5] = 1;
	if(n > 1)power(n - 1);
	printf("%lld", K.h[1][5]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_wujiajie/article/details/111404528
今日推荐