问题 G: 礼物
时间限制: 5 Sec 内存限制: 512 MB提交: 76 解决: 23
[ 提交][ 状态][ 讨论版]
题目描述
热情好客的小猴请森林中的朋友们吃饭,他的朋友被编号为 1∼N,每个到来的朋友都会带给他一些礼物:香蕉。其中,第一个朋友会带给他1个香蕉,之后,每一个朋友到来以后,都会带给他之前所有人带来的礼物个数再加他的编号的K次方那么多个。所以,假设 K=2,前几位朋友带来的礼物个数分别是:
1,5,15,37,83,…
假设 K=3,前几位朋友带来的礼物个数分别是:
1,9,37,111,…
现在,小猴好奇自己到底能收到第 N 个朋友多少礼物,因此拜托于你了。
已知 N,K,请输出第 N 个朋友送的礼物个数 mod 1000000007 。
1,5,15,37,83,…
假设 K=3,前几位朋友带来的礼物个数分别是:
1,9,37,111,…
现在,小猴好奇自己到底能收到第 N 个朋友多少礼物,因此拜托于你了。
已知 N,K,请输出第 N 个朋友送的礼物个数 mod 1000000007 。
输入
第一行,两个整数 N,K。
输出
一个整数,表示第N个朋友送的礼物个数 mod 1000000007。
样例输入
4 2
样例输出
37
提示
100% 的数据:N≤1018,K≤10。
123
分析: 对于 第n 个人说 送的数目 an = S(n-1) +n^k; 则 前 n 个人送的总数目 S(N) = S(N-1) + aN; 于是有 S(N)= 2*S(N-1) + n^k;
构造矩阵:
于是 先打表 k的组合数; 然后 进行矩阵快速幂;
套模板
代码;
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <stdio.h>
#include <cmath>
#include <string>
#include <stack>
typedef long long ll;
const int MOD=1000000007;
const int N =20;
const int MAXN=11;
using namespace std;
ll c[20][20];
ll n;
int k;
ll myc(int n,int r)
{
ll sum=1;
for(int i=1;i<=r;i++)
sum=sum*(n+1-i)/i;
return sum;
}
void init_tab()
{
memset(c,0,sizeof(c));
for(int i=1;i<=10;i++)
for(int j=0;j<=i;j++)
{
c[i][j]=myc(i,j);
}
// for(int i=1;i<=10;i++)
// {
// for(int j=0;j<=i;j++)
// printf("%d ",c[i][j]);
// printf("\n");
// }
}
struct Matrix{
ll arr[N][N];
void init()
{
memset(arr,0,sizeof(arr));
for(int i=0;i<MAXN;i++)
arr[i][i]=1;//初始化
}
void iinit()
{
memset(arr,0,sizeof(arr));
arr[0][0]=2;
for(int i=1;i<=MAXN;i++)
arr[0][i]=arr[1][i]=c[k][i-1];
for(int j=2;j<=MAXN;j++)
for(int i=2;i<=MAXN;i++)
{
arr[j][i+j-2]=c[k-j+1][i-2];
}
// for(int j=0;j<=MAXN;j++)
// {
// for(int i=0;i<=MAXN;i++)
// printf("\t%lld ",arr[j][i]);
// cout<<endl;
//
// }
}
void show()
{
for(int j=0;j<=MAXN;j++)
{
for(int i=0;i<=MAXN;i++)
printf("\t%lld ",arr[j][i]);
cout<<endl;
}
}
}A;
Matrix mul(Matrix X,Matrix Y)// 矩阵乘法
{
Matrix ans;
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++){
ans.arr[i][j]=0;
for(int k=0;k<MAXN;k++){
ans.arr[i][j]+=X.arr[i][k]*Y.arr[k][j];
ans.arr[i][j]%=MOD;
}
}
return ans;
}
Matrix Q_pow(Matrix B,ll n)// 矩阵快速幂
{
Matrix ans;
ans.init();
while(n)
{
if(n&1)
ans=mul(ans,B);
n>>=1;
B=mul(B,B);
}
return ans;
}
int main()
{
init_tab();
scanf("%lld %d",&n,&k);
{
Matrix ans;
if(n<=1)
{
printf("1\n");
return 0;
}
ans.iinit();
ans=Q_pow(ans,n-1);
ll res=0;
for(int i=0;i<=k;i++)
res+=(ans.arr[0][i])%MOD;
printf("%lld\n",res%MOD);
//ans.show();
}
return 0;
}