number number number
We define a sequence FF:
⋅⋅ F0=0,F1=1F0=0,F1=1;
⋅⋅ Fn=Fn−1+Fn−2 (n≥2)Fn=Fn−1+Fn−2 (n≥2).
Give you an integer kk, if a positive number nn can be expressed by
n=Fa1+Fa2+...+Fakn=Fa1+Fa2+...+Fak where 0≤a1≤a2≤⋯≤ak0≤a1≤a2≤⋯≤ak, this positive number is mjf−goodmjf−good. Otherwise, this positive number is mjf−badmjf−bad.
Now, give you an integer kk, you task is to find the minimal positive mjf−badmjf−badnumber.
The answer may be too large. Please print the answer modulo 998244353.
Input
There are about 500 test cases, end up with EOF.
Each test case includes an integer kk which is described above. (1≤k≤1091≤k≤109)
Output
For each case, output the minimal mjf−badmjf−bad number mod 998244353.
Sample Input
1
Sample Output
4
方法一: 找规律,输出 f[2*k+3]-1的值就行,f[i]表示斐波那契数列第i项的值。
方法二:(黑科技),先打表算出前几项,然后用杜教BM线性递推。代码:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (long long i=a;i<n;i++)
#define per(i,a,n) for (long long i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((long long)(x).size())
typedef vector<long long> VI;
typedef long long ll;
typedef pair<long long,long long> PII;
const ll mod=998244353;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
long long _,n;
namespace linear_seq
{
const long long N=10010;
ll res[N],base[N],_c[N],_md[N];
vector<long long> Md;
void mul(ll *a,ll *b,long long k)
{
rep(i,0,k+k) _c[i]=0;
rep(i,0,k) if (a[i]) rep(j,0,k)
_c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
for (long long i=k+k-1;i>=k;i--) if (_c[i])
rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,0,k) a[i]=_c[i];
}
long long solve(ll n,VI a,VI b)
{
ll ans=0,pnt=0;
long long k=SZ(a);
assert(SZ(a)==SZ(b));
rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
Md.clear();
rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
rep(i,0,k) res[i]=base[i]=0;
res[0]=1;
while ((1ll<<pnt)<=n) pnt++;
for (long long p=pnt;p>=0;p--)
{
mul(res,res,k);
if ((n>>p)&1)
{
for (long long i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
if (ans<0) ans+=mod;
return ans;
}
VI BM(VI s)
{
VI C(1,1),B(1,1);
long long L=0,m=1,b=1;
rep(n,0,SZ(s))
{
ll d=0;
rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==0) ++m;
else if (2*L<=n)
{
VI T=C;
ll c=mod-d*powmod(b,mod-2)%mod;
while (SZ(C)<SZ(B)+m) C.pb(0);
rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+1-L; B=T; b=d; m=1;
}
else
{
ll c=mod-d*powmod(b,mod-2)%mod;
while (SZ(C)<SZ(B)+m) C.pb(0);
rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
long long gao(VI a,ll n)
{
VI c=BM(a);
c.erase(c.begin());
rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
};
int main()
{
int x1[]={4,12,33,88,232,609}; //打前几项表用BM线性递推
while(~scanf("%I64d", &n))
{
VI a;
for(int i=0;i<6;++i)
a.push_back(x1[i]);
printf("%I64d\n",linear_seq::gao(a,n-1)%mod);
}
}