题目
给定一个数列满足(a_n=233a_{n-1}+666a_{n-2},a_0=0,a_1=1)
(T)组询问求(a_n mod {10^9+7},Tleq 5 imes 10^7)
分析
首先这道题可以用矩阵快速幂+预处理分块做(不放博客迁移前的链接了),
但是为了锻炼特征方程就来重新做一做这题
首先我们要找到一组(p,q)使得(a_n=(p+q)a_{n-1}+pq imes a_{n-2})
然后根据推导得到
[a_n=frac{a_1-pa_0}{q-p}q^n+frac{a_1-qa_0}{p-q}p^n
]
解出来就是
[p=frac{233+sqrt{56953}}{2},q=frac{233-sqrt{56953}}{2}
]
凡是做了一下二次剩余或者推出来的,应该都知道
(188305837^2equiv 56953 pmod {10^9+7})
最后化简得到
[a_n=233230706(94153035^n-905847205^n)mod {10^9+7}
]
光速幂(分块预处理)一下就可以做到(O(T))了
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
typedef unsigned long long ull; ull sa,sb,sc,temp;
const int A=94153035,B=905847205,C=233230706,mod=1000000007,N=32768;
int T,n,ans,Aa[N+7],Ab[N+7],Ba[N+7],Bb[N+7];
inline signed ksm(int x,int y){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
signed main(){
Aa[0]=Ab[0]=Ba[0]=Bb[0]=1,scanf("%d",&T);
for (rr int i=1;i<=N;++i) Aa[i]=1ll*Aa[i-1]*A%mod;
for (rr int i=1;i<=N;++i) Ba[i]=1ll*Ba[i-1]*B%mod;
for (rr int i=1;i<=N;++i) Ab[i]=1ll*Ab[i-1]*Aa[N]%mod;
for (rr int i=1;i<=N;++i) Bb[i]=1ll*Bb[i-1]*Ba[N]%mod;
for (scanf("%llu%llu%llu",&sa,&sb,&sc);T;--T){
sa^=sa<<32,sa^=sa>>13,sa^=sa<<1,
temp=sa,sa=sb,sb=sc,sc^=temp^sa,n=sc%(mod-1);
rr int t1=1ll*Ab[n>>15]*Aa[n&32767]%mod;
rr int t2=1ll*Bb[n>>15]*Ba[n&32767]%mod;
ans^=1ll*C*(t1-t2+mod)%mod;
}
return !printf("%d",ans);
}