Codeforces 193E - Fibonacci Number(打表找规律+乱搞)

Codeforces 题目传送门 & 洛谷题目传送门

蠢蠢的我竟然第一眼想套通项公式?然鹅显然 \(5\)\(\bmod 10^{13}\) 意义下并没有二次剩余……我真是活回去了。。。

考虑打表找规律(u1s1 这是一个非常有用的技巧,因为这个 \(10^{13}\) 给的就很灵性,用到类似的技巧的题目还有这个,通过对这些模数的循环节打表找出它们的共同性质,所以以后看到什么特殊的数据或者数据范围特别大但读入量 \(\mathcal O(1)\) 的题(比如 CF838D)可以考虑小数据打几个表看看有没有什么共同特征,说不定对解题有些用处),斐波那契数列在模 \(10,100,1000,10000,100000,\cdots\) 意义下的循环节恰好是 \(60,300,1500,15000,150000\),后面依次乘 \(10\)

因此我们考虑这样一个算法,我们考虑枚举 \(f_1,f_2,\cdots,f_{1.5\times 10^6}\),即 Fibonacci 数列在模 \(10^6\) 下的循环节并求出满足 \(f_i\equiv n\pmod{10^6}\)\(i\) 组成的集合 \(S\),然后一步步将模数乘 \(10\) 并生成新的集合 \(S\),具体来说,由于每 \(1.5\times 10^6\) 项斐波那契数列恰好构成一个循环节,因此斐波那契数列模 \(10^7\) 的一个循环节恰好由 \(10\) 个模 \(10^6\) 的循环节组成,因此在一个模 \(10^7\) 的循环节中,所有 \(f_i\)\(n\)\(10^6\) 同余的 \(i\) 一定可以写成 \(kT+x\) 的形式,其中 \(k=0,1,2,\cdots,9,T=1.5\times 10^6,x\in S\),我们只需检验是否 \(f_{kT+x}\equiv n\pmod{10^7}\) 即可求出 \(f_i\equiv n\pmod{10^7}\)\(i\) 组成的集合 \(S\),也就完成了由 \(10^6\to 10^7\) 的转化,如此一直推到 \(10^{13}\) 即可。

时间复杂度 \(\mathcal O(\text{能过})\)

const int T=1.5e6;
const ll MOD=1e13;
const int SMOD=1e6;
const ll INF=1e18;
ll n;
ll smul(ll x,ll y){
	ll ret=0;
	for(;y;y>>=1,(x<<=1)%=MOD) if(y&1) (ret+=x)%=MOD;
	return ret;
}
struct mat{
	ll a[2][2];
	mat(){memset(a,0,sizeof(a));}
	mat operator *(const mat &rhs){
		mat ret;
		for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++)
			ret.a[i][j]+=smul(a[i][k],rhs.a[k][j]);
		for(int i=0;i<2;i++) for(int j=0;j<2;j++) ret.a[i][j]%=MOD;
		return ret;
	}
};
ll getf(ll ps){
	mat bs;bs.a[0][1]=bs.a[1][0]=bs.a[1][1]=1;
	mat rs;rs.a[0][0]=rs.a[1][1]=1;
	for(;ps;ps>>=1,bs=bs*bs) if(ps&1) rs=rs*bs;
	return rs.a[1][0];
}
vector<ll> can,tmp;
int main(){
	scanf("%lld",&n);
	for(ll i=1,p=0,q=1;i<=T;i++){
		if(q%SMOD==n%SMOD) can.pb(i);
		p=(p+q)%MOD;p^=q^=p^=q;
	} ll CT=T,CMOD=SMOD;
	while(CMOD^MOD){
		tmp.clear();CMOD*=10;
		for(ll x:can) for(int i=0;i<=9;i++)
			if(getf(CT*i+x)%CMOD==n%CMOD) tmp.pb(CT*i+x);
		swap(tmp,can);CT*=10;
	} ll res=INF;for(ll x:can) chkmin(res,x);
	printf("%lld\n",(res==INF)?-1:res);
	return 0;
}
posted @ 2021-06-02 20:50  tzc_wk  阅读(277)  评论(0编辑  收藏  举报