题目描述

热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1~N,每个到来的朋友都会带给他一些礼物:。其中,第一个朋友会带给他 1 个,之后,每一个朋友到来以后,都会带给他之前所有人带来的礼物个数再加他的编号的 K 次方那么多个。所以,假设 K=2,前几位朋友带来的礼物个数分别是:1,5,15,37,83假设 K=3,前几位朋友带来的礼物个数分别是:1,9,37,111现在,好奇自己到底能收到第 N 个朋友多少礼物,因此拜托于你了。已知 N,K请输出第 N 个朋友送的礼物个数 mod1000000007。

输入

第一行,两个整数 N,K
N≤10^18,K≤10

输出

一个整数,表示第 N 个朋友送的礼物个数 mod1000000007。 

样例输入

4 2

样例输出

37


题解

矩阵乘法

设前$i$项的和为$S_i$,那么根据定义有$a_n=S_{n-1}+n^k$,故有$S_n=S_{n-1}+a_n=2S_{n-1}+n^k$。

由于k不大,显然这个式子可以矩乘。

具体方法:维护矩阵$\begin{bmatrix}S_{n-1}&n^k&n^{k-1}&...&n^1&n^0\end{bmatrix}$,那么$S$的转移矩阵就是上面的式子,而$n^i$的转移矩阵就是二项式系数,即$(n+1)^i$的展开式。

于是矩阵乘法加速递推,最终的答案就是$S_n-S_{n-1}$。

时间复杂度$O(k^3\log n)$

#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 1000000007
using namespace std;
typedef long long ll;
int d;
struct data
{
ll v[12][12];
ll* operator[](int a) {return v[a];}
data() {memset(v , 0 , sizeof(v));}
data operator*(data a)
{
data ans;
int i , j , k;
for(i = 0 ; i <= d + 1 ; i ++ )
for(j = 0 ; j <= d + 1 ; j ++ )
for(k = 0 ; k <= d + 1 ; k ++ )
ans[i][j] = (ans[i][j] + v[i][k] * a[k][j]) % mod;
return ans;
}
}A , P;
data pow(data x , ll y)
{
data ans;
int i;
for(i = 0 ; i <= d + 1 ; i ++ ) ans[i][i] = 1;
while(y)
{
if(y & 1) ans = ans * x;
x = x * x , y >>= 1;
}
return ans;
}
int main()
{
ll n;
int i , j;
scanf("%lld%d" , &n , &d);
for(i = 1 ; i <= d + 1 ; i ++ ) A[0][i] = 1;
P[0][0] = 2 , P[1][0] = 1;
for(i = d + 1 ; i ; i -- )
{
P[d + 1][i] = 1;
for(j = d ; j >= i ; j -- ) P[j][i] = P[j + 1][i + 1] + P[j][i + 1];
}
A = A * pow(P , n - 1);
printf("%lld\n" , ((A * P)[0][0] - A[0][0] + mod) % mod);
return 0;
}

【bzoj5015】[Snoi2017]礼物 矩阵乘法的更多相关文章

  1. bzoj 5015 [Snoi2017]礼物 矩阵乘法

    5015: [Snoi2017]礼物 Time Limit: 15 Sec  Memory Limit: 512 MBSubmit: 163  Solved: 115[Submit][Status][ ...

  2. bzoj5015 [Snoi2017]礼物 矩阵快速幂+二项式展开

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5015 题解 设 \(f_i\) 表示第 \(i\) 个朋友的礼物,\(s_i\) 表示从 \( ...

  3. [bzoj5015][Snoi2017]礼物

    来自FallDream的博客,未经允许,请勿转载,谢谢. 热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1-N,每个到来的朋友都会带给他一些礼物:.其中,第一个朋友会带给他 1 个,之后,每一个朋 ...

  4. BZOJ_5015_[Snoi2017]礼物_矩阵乘法

    BZOJ_5015_[Snoi2017]礼物_矩阵乘法 Description 热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1-N,每个到来的朋友都会带给他一些礼物:.其中,第 一个朋友会带给他 ...

  5. SNOI2017 礼物

    题解 设前\(n\)个人的礼物个数和为\(F_n\), 那么显然\[F_n = 2 \times F_{n-1} + i^k\] 考虑矩阵快速幂 棘手的问题是:\(i^k\)不是可以直接用矩阵乘法可以 ...

  6. *HDU2254 矩阵乘法

    奥运 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...

  7. *HDU 1757 矩阵乘法

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  8. CH Round #30 摆花[矩阵乘法]

    摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...

  9. POJ3070 Fibonacci[矩阵乘法]

    Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13677   Accepted: 9697 Descri ...

随机推荐

  1. XML DTD约束 对xml文件的crud的查询Read Retrieve操作 xml递归遍历

    本地的dtd文档 xml中引入dtd文档 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE 书 ...

  2. Python 初始—(字符编码解码)

    字符编码之间的编码转换则需要通过Unicode 进行转换,那么需要一个编码和解码实现与Unicode进行关联转换 例如utf-8转gbk utf-8----decode----->Unicode ...

  3. 【杂题总汇】UVa-1627 Team them up!

    [UVa-1627] Team them up! 借鉴了一下hahalidaxin的博客……了解了思路,但是莫名Wa了:最后再找了一篇dwtfukgv的博客才做出来

  4. 【杂题总汇】UVa-10618 Tango Tango Insurrection

    [UVa-10618] Tango Tango Insurrection ◇ 题目 +vjudge 链接+ (以下选自<算法竞赛入门经典>-刘汝佳,有删改) <题目描述> 你想 ...

  5. sql的使用

    1.自动获取最新订单号 select concat('XJDD',DATE_FORMAT(now(),'%Y%m%d'), LPAD(( FOR )) , max(SUBSTRING(inquiryn ...

  6. (三)Swagger配置多项目共用

    重构了多个项目后,在联调接口时,查看api会发现Swagger在几个项目可用,有几个不可用,配置都一样,扫描也充分,那问题出在哪里呢?先仔细找了下Docket的源码,发现有这么个方法: /** * P ...

  7. 【转载】VS2015 + EF6连接MYSQL5.6

    引用文章:https://jingyan.baidu.com/article/ce09321b9cc43f2bff858fbf.html 安装包注意点说明: 1.程序名称:mysql-for-visu ...

  8. 为什么 redis 单线程却能支撑高并发

    redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 这个是问 redis 的时候,最基本的问题吧,redis 最基本的一个内部原理 ...

  9. php结合redis实现高并发下的抢购、秒杀功能【转】

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  10. 生产-消费模式的synchronized和lock实现(十)

    lock: package com.net.thread.lock; import java.util.concurrent.locks.Condition; import java.util.con ...