original link - https://nanti.jisuanke.com/t/41355
题意:
求 F n = 3 F n − 1 + 2 F n − 2 , F 0 = 0 , F 1 = 1 F_n=3F_{n-1}+2F_{n-2},F_0=0,F_1=1 Fn=3Fn−1+2Fn−2,F0=0,F1=1的第 n n n项 % 998244353 \% 998244353 %998244353( n ∈ [ 1 , 1 e 18 ] n\in[1,1e18] n∈[1,1e18])
解析:
F n + 1 + − 3 + 17 2 F n = 3 + 17 2 ( F n + − 3 + 17 2 F n − 1 ) F_{n+1}+\dfrac{-3+\sqrt {17}}{2}F_{n}=\dfrac{3+\sqrt {17}}{2}(F_{n}+\dfrac{-3+\sqrt {17}}{2}F_{n-1}) Fn+1+2−3+17Fn=23+17(Fn+2−3+17Fn−1)
F n + 1 + − 3 − 17 2 F n = 3 − 17 2 ( F n + − 3 − 17 2 F n − 1 ) F_{n+1}+\dfrac{-3-\sqrt {17}}{2}F_{n}=\dfrac{3-\sqrt {17}}{2}(F_{n}+\dfrac{-3-\sqrt {17}}{2}F_{n-1}) Fn+1+2−3−17Fn=23−17(Fn+2−3−17Fn−1)
∵ F 1 + − 3 + 17 2 F 0 = 1 \because F_1+\dfrac{-3+\sqrt {17}}{2}F_{0}=1 ∵F1+2−3+17F0=1
∴ F n + 1 + − 3 + 17 2 F n = ( 3 + 17 2 ) n , F n + 1 + − 3 − 17 2 F n = ( 3 − 17 2 ) n \therefore F_{n+1}+\dfrac{-3+\sqrt {17}}{2}F_{n}=(\dfrac{3+\sqrt {17}}{2})^n,F_{n+1}+\dfrac{-3-\sqrt {17}}{2}F_{n}=(\dfrac{3-\sqrt {17}}{2})^n ∴Fn+1+2−3+17Fn=(23+17)n,Fn+1+2−3−17Fn=(23−17)n
∴ 17 F n = ( 3 + 17 2 ) n − ( 3 − 17 2 ) n \therefore \sqrt{17}F_n=(\dfrac{3+\sqrt {17}}{2})^n-(\dfrac{3-\sqrt {17}}{2})^n ∴17Fn=(23+17)n−(23−17)n
怎么求 ( 3 + 17 2 ) n − ( 3 − 17 2 ) n (\dfrac{3+\sqrt {17}}{2})^n-(\dfrac{3-\sqrt {17}}{2})^n (23+17)n−(23−17)n呢?
首先 17 \sqrt{17} 17用二次剩余展开为 524399943 524399943 524399943,前面那部分在模 998244353 998244353 998244353的循环节为 249561088 249561088 249561088,后面的为 29360128 29360128 29360128,那么就预处理下 x 100 k x^{100k} x100k,最后的 100 100 100内的也打一下。之后就可以 O ( 1 ) O(1) O(1)求了。
代码:
/*
* Author : Jk_Chen
* Date : 2019-09-08-14.12.16
*/
#include
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<
const LL mod=998244353;
const int maxn=1e5+9;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
/*_________________________________________________________head*/
LL Pow(LL a,LL b,LL mod){
LL res=1;
while(b>0){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
//524399943 473844410
LL sq17=524399943,inv2=Pow(2,mod-2,mod),inv_sq17=Pow(524399943,mod-2,mod);
LL P1[2495620],PP1[110];
LL P2[293611],PP2[110];
LL deal(LL n){
if(n==0)return 0;
if(n==1)return 1;
LL n1=n%249561088;
LL n2=n%29360128;
LL m1=P1[n1/100]*PP1[n1%100]%mod;
LL m2=P2[n2/100]*PP2[n2%100]%mod;
return (m1+mod-m2)%mod*inv_sq17%mod;
}
int main(){
// int ct=0;
// LL now=1;
// while(1){
// ct++;
// now=now*mul2%mod;
// if(now==1)break;
// }
// printf("%d\n",ct);
LL mul1=(3+sq17)*inv2%mod; // 249561088
LL mul2=(mod+3-sq17)*inv2%mod; // 29360128
PP1[0]=PP2[0]=1;
rep(i,1,100)
PP1[i]=PP1[i-1]*mul1%mod,
PP2[i]=PP2[i-1]*mul2%mod;
P1[0]=P2[0]=1;
rep(i,1,2495610){
P1[i]=P1[i-1]*PP1[100]%mod;
}
rep(i,1,293601){
P2[i]=P2[i-1]*PP2[100]%mod;
}
LL q=rd(),n=rd();
LL lastans=0;
LL all=0;
while(q--){
n=(lastans*lastans)^n;
LL ans=deal(n);
lastans=ans;
all^=ans;
}
printf("%lld\n",all);
return 0;
}