这是一道恶心的数学题,令人谔谔!
大家都看过题面了吧?我现在来说说我的思路。
首先我在这篇博客中提出了 S n − 2 + 1 = F n S_{n-2}+1=F_n Sn−2+1=Fn 即 S n = F n + 2 − 1 S_n=F_{n+2}-1 Sn=Fn+2−1。
然后看题目给出的柿子。把他变成一个三角形:
F
1
F_1
F1
F
2
F
2
F_2 \ \ F_2
F2 F2
F
3
F
3
F
3
F_3 \ \ F_3 \ \ F_3
F3 F3 F3
F
4
F
4
F
4
F
4
F_4 \ \ F_4 \ \ F_4 \ \ F_4
F4 F4 F4 F4
F
5
F
5
F
5
F
5
F
5
F_5 \ \ F_5 \ \ F_5 \ \ F_5 \ \ F_5
F5 F5 F5 F5 F5
…
…
…
…
\texttt{…………}
…………
答案就是这个三角形内所有数之和。
我们可以把这个三角形竖着看,发现了啥?这个式子就是:
∑ i = 1 n ( S n − S i − 1 ) \sum \limits_{i=1}^n (S_n-S_{i-1}) i=1∑n(Sn−Si−1)
把 S n S_n Sn 提取出来:
n S n − ∑ i = 1 n S i − 1 nS_n-\sum\limits_{i=1}^nS_{i-1} nSn−i=1∑nSi−1
这个时候, S n = F n + 2 − 1 S_n=F_{n+2}-1 Sn=Fn+2−1 派上用场了。把这个柿子往里面套啊!
n ( F n + 2 − 1 ) − ∑ i = 1 n ( F i + 1 − 1 ) n(F_{n+2}-1) - \sum\limits_{i=1}^n (F_{i+1}-1) n(Fn+2−1)−i=1∑n(Fi+1−1)
发现了啥? ∑ i = 1 n ( F i + 1 − 1 ) \sum\limits_{i=1}^n (F_{i+1}-1) i=1∑n(Fi+1−1) 其实也可以转化为 S n + 1 − F 1 − n S_{n+1}-F_1-n Sn+1−F1−n。
把 S n = F n + 2 − 1 S_n=F_{n+2}-1 Sn=Fn+2−1 再往 S n + 1 S_{n+1} Sn+1 里面套!
答案就变成了:
n
(
F
n
+
2
−
1
)
−
(
F
n
+
3
−
1
−
F
1
−
n
)
\ \ \ \ n(F_{n+2}-1)- (F_{n+3}-1-F_1-n)
n(Fn+2−1)−(Fn+3−1−F1−n)
=
n
F
n
+
2
−
n
−
F
n
+
3
+
1
+
F
1
+
n
=nF_{n+2}-n-F_{n+3}+1+F_1+n
=nFn+2−n−Fn+3+1+F1+n
=
n
F
n
+
2
−
F
n
+
3
+
2
=nF_{n+2}-F_{n+3}+2
=nFn+2−Fn+3+2
一个矩阵加速就搞定了。
恶心至极啊!
code: \text{code:} code:
#include<cstdio>
using namespace std;
long long n,m;
struct mat{
long long a[5][5];
};
inline void clear(mat &z)
{
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++) z.a[i][j]=0;
}
inline mat operator* (mat A,mat B)
{
mat c;clear(c);
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
c.a[i][j]=(c.a[i][j]+A.a[i][k]*B.a[k][j])%m;
return c;
}
inline mat operator^ (mat A,long long b)
{
mat c;clear(c);
c.a[1][1]=c.a[1][2]=1;
mat base=A;
while(b)
{
if(b&1) c=c*base;
base=base*base;
b/=2;
}
return c;
}
int main()
{
scanf("%lld%lld",&n,&m);
if(n==1) {printf("%lld\n",1%m);return 0;}
mat first;clear(first);
first.a[1][1]=first.a[1][2]=first.a[2][1]=1;
long long tmp1=n*((first^(n)).a[1][1])%m;
long long tmp2=((first^(n+1)).a[1][1])%m;
printf("%lld\n",(tmp1-tmp2+2+m)%m);
return 0;
}