BZOJ5221[Lydsy2017省队十连测] 偏题

原题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5221

偏题

Description

斐波那契数列是一个经典递推数列,即
F i b n = F i b n − 1 + F i n + n − 2 Fib_n=Fib_{n-1}+Fin+{n-2} Fibn=Fibn1+Fin+n2

在这个问题中,定义一个新数列,对于 n ≥ 2 n ≥ 2 n2
F n = F n − 1 + F n − 2 + 2 3 + F n − 1 F n − 2 F_n=F_{n-1}+F_{n-2}+2\sqrt{3+F_{n-1}F_{n-2}} Fn=Fn1+Fn2+23+Fn1Fn2

对于给出的四个整数 F 0 , F 1 , M , n F_0,F_1,M,n F0,F1,M,n,求 F n   m o d   M F_n\ mod\ M Fn mod M

数据保证 3 + F n − 1 F n − 2 \sqrt{3+F_{n-1}F_{n-2}} 3+Fn1Fn2 总是整数。

Input

一行四个整数 F 0 , F 1 , M , n F_0,F_1,M,n F0,F1,M,n

Output

一行一个整数,表示 F n F_n Fn M M M取模后的值。

Sample Input

1 1 10 5

Sample Output

4

HINT

F 0 = 1 F_0=1 F0=1
F 1 = 1 F_1=1 F1=1
F 2 = 1 + 1 + 2 3 + 1 × 1 = 6 F_2=1+1+2\sqrt{3+1\times 1}=6 F2=1+1+23+1×1 =6
F 3 = 6 + 1 + 2 3 + 6 × 1 = 13 F_3=6+1+2\sqrt{3+6\times 1}=13 F3=6+1+23+6×1 =13
F 4 = 13 + 6 + 2 3 + 13 × 6 = 37 F_4=13+6+2\sqrt{3+13×6}=37 F4=13+6+23+13×6 =37
F 5 = 37 + 13 + 2 3 + 37 × 13 = 94 F_5=37+13+2\sqrt{3+37×13}=94 F5=37+13+23+37×13 =94

【数据规模】

对于 30 % 30\% 30%的数据, n ≤ 20 n≤20 n20

对于 60 % 60\% 60%的数据, F 0 = F 1 = 1 F_0=F_1=1 F0=F1=1

对于 80 % 80\% 80%的数据, n ≤ 1 0 5 n≤10^5 n105

对于 100 % 100\% 100%的数据, 0 ≤ n ≤ 1 0 9 , 1 ≤ M ≤ 1 0 9 , 1 ≤ F 0 ≤ F 1 ≤ 1 0 6 0≤n≤10^9,1≤M≤10^9,1≤F_0≤F_1≤10^6 0n1091M1091F0F1106

题解

乍一看可能需要一个二次剩余,然而我们可以先推个式子:

( 3 + F n F n − 1 ) 2 (\sqrt{3+F_nF_{n-1}})^2 (3+FnFn1 )2
= 3 + F n F n − 1 =3+F_nF_{n-1} =3+FnFn1
= 3 + ( F n − 1 + F n − 2 + 2 3 + F n − 1 F n − 2 ) F n − 1 =3+(F_{n-1}+F_{n-2}+2\sqrt{3+F_{n-1}F_{n-2}})F_{n-1} =3+(Fn1+Fn2+23+Fn1Fn2 )Fn1
= 3 + F n − 1 F n − 2 + 2 F n − 1 3 + F n − 1 F n − 2 + F n − 1 2 =3+F_{n-1}F_{n-2}+2F_{n-1}\sqrt{3+F_{n-1}F_{n-2}}+F_{n-1}^2 =3+Fn1Fn2+2Fn13+Fn1Fn2 +Fn12
= ( 3 + F n − 1 F n − 2 + F n − 1 ) 2 =(\sqrt{3+F_{n-1}F_{n-2}}+F_{n-1})^2 =(3+Fn1Fn2 +Fn1)2

话说为什么 C S D N \mathcal{CSDN} CSDN改版以后左对齐的语法不管用了。。。

源码如下:

\begin{align*}
&(\sqrt{3+F_nF_{n-1}})^2\\
&=3+F_nF_{n-1}\\
&=3+(F_{n-1}+F_{n-2}+2\sqrt{3+F_{n-1}F_{n-2}})F_{n-1}\\
&=3+F_{n-1}F_{n-2}+2F_{n-1}\sqrt{3+F_{n-1}F_{n-2}}+F_{n-1}^2\\
&=(\sqrt{3+F_{n-1}F_{n-2}}+F_{n-1})^2
\end{align*}

所以就有 3 + F n F n − 1 = 3 + F n − 1 F n − 2 + F n − 1 \sqrt{3+F_nF_{n-1}}=\sqrt{3+F_{n-1}F_{n-2}}+F_{n-1} 3+FnFn1 =3+Fn1Fn2 +Fn1,这样我们就可以将 3 + F n F n − 1 \sqrt{3+F_nF_{n-1}} 3+FnFn1 当做一项放进矩阵里递推了。

初始矩阵:

1 1 1
1 0 0
2 0 1

快速幂出来了以后再乘上一个向量 F 1 , F 0 , 3 + F 0 F 1 F_1,F_0,\sqrt{3+F_0F_1} F1,F0,3+F0F1 就行了。

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=105;
ll n=3,mod,a,f0,f1;
struct matrix{int sq[M][M];matrix(){memset(sq,0,sizeof(sq));}}mat,one;
matrix operator *(matrix a,matrix b)
{matrix c;for(int i=1,j,k;i<=n;++i)for(j=1;j<=n;++j)for(k=1;k<=n;++k)(c.sq[i][j]+=1ll*a.sq[i][k]*b.sq[k][j]%mod)%=mod;return c;}
matrix power(matrix x,ll p){matrix ans=one;for(;p;p>>=1,x=x*x)if(p&1)ans=ans*x;return ans;}
void in(){scanf("%lld%lld%lld%lld",&f0,&f1,&mod,&a);}
void ac()
{
	one.sq[1][1]=one.sq[2][2]=one.sq[3][3]=1;
	mat.sq[1][1]=mat.sq[1][2]=mat.sq[1][3]=mat.sq[2][1]=mat.sq[3][3]=1,mat.sq[3][1]=2;
	mat=power(mat,a-1);
	printf("%lld\n",(mat.sq[1][1]*f1%mod+mat.sq[2][1]*f0%mod+mat.sq[3][1]*(ll)sqrt(3+f0*f1)%mod)%mod);
}
int main(){in();ac();}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值