题意:有n个人,1到m个数,这n个人,每人选一个数字,要求相邻的两个人选择的数不能相等,相等时不能小于k
a[i] 表示第i位置的>k的种数 。
b[i]表示第i位置<=k的种数。
a[1]=m-k; b[1]=k;
用矩阵求解;
#include<stdio.h>
const long long mod=1000000007;
long long a[4],b[4];
long long m,k;
void fun(long long t)
{
b[0]=( (a[0]*a[0])%mod+(a[1]*a[2])%mod )%mod;
b[1]=( (a[0]*a[1])%mod+(a[1]*a[3])%mod )%mod;
b[2]=( (a[2]*a[0])%mod+(a[3]*a[2])%mod )%mod;
b[3]=( (a[2]*a[1])%mod+(a[3]*a[3])%mod )%mod;
a[0]=b[0]; a[1]=b[1];
a[2]=b[2]; a[3]=b[3];
if(t)
{
b[0]=( a[0]*(m-k)%mod + a[1]*(m-k)%mod)%mod;
b[1]=(a[0]*k%mod+a[1]*(k-1)%mod)%mod;
b[2]=(a[2]*(m-k)%mod+a[3]*(m-k)%mod)%mod;
b[3]=(a[2]*k%mod+a[3]*(k-1)%mod)%mod;
a[0]=b[0]; a[1]=b[1];
a[2]=b[2]; a[3]=b[3];
}
}
void fib(long long n)
{
if(n == 1) return;
fib(n/2);
if(n%2==1) fun(1);
else fun(0);
}
int main()
{
long long n;
while(scanf("%lld%lld%lld",&n,&m,&k)!=EOF)
{
a[0]=m-k;a[1]=k;
a[2]=m-k; a[3]=k-1;
fib(n);
printf("%lld\n",(a[0]%mod+a[1]%mod)%mod);
}
return 0;
}