Codeforces 717A. Festival Organization (2900)

一个合法的串定义为:长度在 \([l,r]\) 之间,且只含 \(0,1\),并且不存在连续 \(2\) 个或更多的 \(0\)
现在要选出 \(k\) 个长度相同的合法的串,问有几种选法,答案对 \(10^9+7\) 取模。
\(1\le k\le 200,1\le l\le r\le 10^{18}\)


通过简单计算,可以发现答案即为 \(\sum_{i=l+2}^{r+2}\binom{F_{i}}{k}\)

\[\begin{aligned} \sum_{i=l+2}^{r+2}\binom{F_{i}}{k}&=\sum_{i=l+2}^{r+2}\frac{F_i^\underline{k}}{k!}\\ &=\frac{1}{k!}\sum_{i=l+2}^{r+2}\sum_{j=0}^{k}(-1)^{k-j}\begin{bmatrix}k\\j\end{bmatrix}F_i^{j}\\ &=\frac{1}{k!}\sum_{j=0}^{k}(-1)^{k-j}\begin{bmatrix}k\\j\end{bmatrix}\sum_{i=l+2}^{r+2}F_i^j \end{aligned} \]

第一类斯特林数可以 \(O(k^2)\) 求出,那么要计算的就是斐波那契数列 \(k\) 次方的前缀和。

考虑将通项公式 \(F_n=\frac{1}{\sqrt{5}}(\frac{1+\sqrt{5}}{2})^n-\frac{1}{\sqrt{5}}(\frac{1-\sqrt{5}}{2})^n\) 写作 \(F_{n}=ax^n-ay^n\) 代入。

\[\begin{aligned} \sum_{i=1}^{n}F_{i}^{k}&=\sum_{i=1}^{n}(ax^i-ay^i)^k\\ &=\sum_{i=1}^{n}\sum_{j=0}^{k}(-1)^{k-j}a^k\binom{k}{j}x^{ij}y^{i(k-j)}\\ &=a^k\sum_{j=0}^{k}(-1)^{k-j}\binom{k}{j}\sum_{i=1}^{n}(x^jy^{k-j})^i\\ &=a^k\sum_{j=0}^{k}(-1)^{k-j}\binom{k}{j}\frac{[(x^jy^{k-j})^n-1]x^jy^{k-j}}{x^jy^{k-j}-1} \end{aligned} \]

由于 \(5\) 在模 \(10^9+7\) 意义下没有二次剩余,所以用扩域记作 \(a+b\sqrt{5}\) 的形式。注意等比数列求和中 \(x^jy^{k-j}=1\) 时特判即可。

总时间复杂度 \(O(k^2\log r)\)

\(\color{blue}{\text{code}}\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=305,mod=1e9+7;
struct Complex{ll x,y;};
inline ll qpow(ll a,ll b){
	ll ans=1;
	for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
	return ans;
}
const Complex X1={qpow(2,mod-2),qpow(2,mod-2)},X2={qpow(2,mod-2),mod-qpow(2,mod-2)};
int k;ll l,r,s[N][N],fac[N],inv[N],Inv[N];Complex ans;
inline Complex operator * (Complex x,ll y){return{x.x*y%mod,x.y*y%mod};}
inline Complex operator + (Complex x,Complex y){return{(x.x+y.x)%mod,(x.y+y.y)%mod};}
inline Complex operator - (Complex x,Complex y){return{(x.x-y.x+mod)%mod,(x.y-y.y+mod)%mod};}
inline Complex operator * (Complex x,Complex y){return{(x.x*y.x+5*x.y*y.y)%mod,(x.x*y.y+x.y*y.x)%mod};}
inline Complex operator / (Complex x,Complex y){
	Complex z=y;if(z.y!=0)z.y=mod-z.y;
	return x*z*qpow((y.x*y.x%mod-5*y.y*y.y%mod+mod)%mod,mod-2);
}
inline Complex cpow(Complex a,ll b){
	Complex ans={1,0};
	for(;b;b>>=1,a=a*a)if(b&1)ans=ans*a;
	return ans;
}
inline void precalc(int n){
	fac[0]=inv[0]=Inv[0]=fac[1]=inv[1]=Inv[1]=1;
	for(int i=2;i<=n;++i)
		fac[i]=fac[i-1]*i%mod,
		Inv[i]=(mod-mod/i)*Inv[mod%i]%mod,
		inv[i]=inv[i-1]*Inv[i]%mod;
}
inline ll C(int n,int m){return fac[n]*inv[m]%mod*inv[n-m]%mod;}
inline Complex SF(ll n,int k){
	Complex res={0,0};
	for(int i=0;i<=k;++i){
		Complex co=cpow(X1,i)*cpow(X2,k-i),oc;
		if(co.x==1&&co.y==0)oc=co*n*C(k,i);
		else oc=co*(cpow(co,n)-(Complex){1,0})/(co-(Complex){1,0})*C(k,i);
		if((k-i)&1)res=res-oc;else res=res+oc;
	}
	return res;
}
int main(){
	precalc(N-1);
	scanf("%d%lld%lld",&k,&l,&r),l+=2,r+=2,s[0][0]=1;
	for(int i=1;i<=k;++i)
		for(int j=1;j<=i;++j)
			s[i][j]=(s[i-1][j-1]+s[i-1][j]*(i-1))%mod;
	for(int i=0;i<=k;++i){
		Complex F=(SF(r,i)-SF(l-1,i))*s[k][i]*cpow({0,qpow(5,mod-2)},i);
		if((k-i)&1)ans=ans-F;else ans=ans+F;
	}
	return printf("%lld\n",ans.x*inv[k]%mod),0;
}
posted @ 2022-07-24 13:28  Samsara-soul  阅读(31)  评论(0编辑  收藏  举报