# codeforces 717A. Festival Organization

$f_n=\sum_{i=0}^n\dbinom{fib_i}{k}$，那么答案也就是$f_{r+2}-f_{l+1}$

\begin{aligned} f_n=&\sum_{i=0}^n\frac{fib_i!}{k!(fib_i-k)!}\\ =&\frac{1}{k!}\sum_{i=0}^n\frac{fib_i!}{(fib_i-k)!}\\ =&\frac{1}{k!}\sum_{i=0}^nfib_i^{\underline{k}}\\ =&\frac{1}{k!}\sum_{i=0}^n\sum_{j=0}^k(-1)^{j-k}\begin{bmatrix}k\\j\end{bmatrix}fib_i^j\\ =&\frac{1}{k!}\sum_{j=0}^k\begin{bmatrix}k\\j\end{bmatrix}(-1)^{k-j}\sum_{i=0}^nfib_i^j \end{aligned}

$\sum_{i=0}^nfib_i^j=\sum_{i=0}^n\frac{(a^i-b^i)^j}{(\sqrt5)^j}=\frac{\sum_{k=0}^j {j\choose k}(-1)^k\sum_{i=0}^n(b^ka^{j-k})^i}{(\sqrt5)^j}$

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define fir first
#define sec second
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define maxd 1000000007
#define inv2 500000004
#define eps 1e-6
typedef long long ll;
const int N=200;
const double pi=acos(-1.0);
int k;
ll l,r,c[220][220],s[220][220],invk=1;

ll qpow(ll x,ll y)
{
ll ans=1;
while (y)
{
if (y&1) ans=ans*x%maxd;
x=x*x%maxd;y>>=1;
}
return ans;
}
struct Complex{
ll x,y;
Complex(ll _x=0,ll _y=0) {x=_x;y=_y;}
};
Complex operator +(Complex a,Complex b)
{
return Complex((a.x+b.x)%maxd,(a.y+b.y)%maxd);
}

Complex operator -(Complex a,Complex b)
{
return Complex((a.x-b.x+maxd)%maxd,(a.y-b.y+maxd)%maxd);
}

Complex operator *(Complex a,Complex b)
{
return Complex((a.x*b.x+a.y*b.y%maxd*5)%maxd,(a.x*b.y+a.y*b.x)%maxd);
}

Complex operator /(Complex a,Complex b)
{
a=a*Complex(b.x,maxd-b.y);b=b*Complex(b.x,maxd-b.y);
ll inv=qpow(b.x,maxd-2);
a.x=a.x*inv%maxd;a.y=a.y*inv%maxd;
return a;
}

Complex qpow(Complex a,ll y)
{
Complex ans=Complex(1,0);
while (y)
{
if (y&1) ans=ans*a;
a=a*a;y>>=1;
}
return ans;
}

void init()
{
s[0][0]=1;c[0][0]=1;
rep(i,1,N)
{
c[i][0]=1;
rep(j,1,i)
{
c[i][j]=(c[i-1][j-1]+c[i-1][j])%maxd;
s[i][j]=(s[i-1][j-1]+s[i-1][j]*(i-1))%maxd;
}
}
rep(i,1,k) invk=invk*i%maxd;
invk=qpow(invk,maxd-2);
}

Complex calc(Complex a,ll n)
{
Complex tmp=Complex(1,0);
if((a.x==1) && (!a.y)) return Complex((n+1)%maxd,0);
else return (qpow(a,n+1)-tmp)/(a-tmp);
}

ll solve(ll n)
{
Complex a=Complex(inv2,inv2),b=Complex(inv2,maxd-inv2);
ll ans=0;
rep(i,0,k)
{
ll now=s[k][i];
if ((k-i)&1) now=(maxd-now)%maxd;
Complex sum=Complex(0,0);
rep(j,0,i)
{
Complex tmp1=Complex(0,0);
if (j&1) tmp1.x=maxd-c[i][j];else tmp1.x=c[i][j];
tmp1=tmp1*calc(qpow(b,j)*qpow(a,i-j),n);
sum=sum+tmp1;
}
Complex inv=Complex();
if (i&1) inv.y=qpow(5,i/2);else inv.x=qpow(5,i/2);
sum=sum/inv;
ans=(ans+now*sum.x)%maxd;
}
ans=ans*invk%maxd;
return ans;
}

int main()
{
scanf("%d%lld%lld",&k,&l,&r);
init();
printf("%lld",(solve(r+2)-solve(l+1)+maxd)%maxd);
return 0;
}

posted @ 2019-05-23 14:37  EncodeTalker  阅读(170)  评论(0编辑  收藏