【bzoj5015】[Snoi2017]礼物 矩阵乘法
题目描述
热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1~N,每个到来的朋友都会带给他一些礼物:。其中,第一个朋友会带给他 1 个,之后,每一个朋友到来以后,都会带给他之前所有人带来的礼物个数再加他的编号的 K 次方那么多个。所以,假设 K=2,前几位朋友带来的礼物个数分别是:1,5,15,37,83假设 K=3,前几位朋友带来的礼物个数分别是:1,9,37,111现在,好奇自己到底能收到第 N 个朋友多少礼物,因此拜托于你了。已知 N,K请输出第 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]礼物 矩阵乘法的更多相关文章
- bzoj 5015 [Snoi2017]礼物 矩阵乘法
5015: [Snoi2017]礼物 Time Limit: 15 Sec Memory Limit: 512 MBSubmit: 163 Solved: 115[Submit][Status][ ...
- bzoj5015 [Snoi2017]礼物 矩阵快速幂+二项式展开
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5015 题解 设 \(f_i\) 表示第 \(i\) 个朋友的礼物,\(s_i\) 表示从 \( ...
- [bzoj5015][Snoi2017]礼物
来自FallDream的博客,未经允许,请勿转载,谢谢. 热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1-N,每个到来的朋友都会带给他一些礼物:.其中,第一个朋友会带给他 1 个,之后,每一个朋 ...
- BZOJ_5015_[Snoi2017]礼物_矩阵乘法
BZOJ_5015_[Snoi2017]礼物_矩阵乘法 Description 热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1-N,每个到来的朋友都会带给他一些礼物:.其中,第 一个朋友会带给他 ...
- SNOI2017 礼物
题解 设前\(n\)个人的礼物个数和为\(F_n\), 那么显然\[F_n = 2 \times F_{n-1} + i^k\] 考虑矩阵快速幂 棘手的问题是:\(i^k\)不是可以直接用矩阵乘法可以 ...
- *HDU2254 矩阵乘法
奥运 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- *HDU 1757 矩阵乘法
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- CH Round #30 摆花[矩阵乘法]
摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...
- POJ3070 Fibonacci[矩阵乘法]
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13677 Accepted: 9697 Descri ...
随机推荐
- XML DTD约束 对xml文件的crud的查询Read Retrieve操作 xml递归遍历
本地的dtd文档 xml中引入dtd文档 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE 书 ...
- Python 初始—(字符编码解码)
字符编码之间的编码转换则需要通过Unicode 进行转换,那么需要一个编码和解码实现与Unicode进行关联转换 例如utf-8转gbk utf-8----decode----->Unicode ...
- 【杂题总汇】UVa-1627 Team them up!
[UVa-1627] Team them up! 借鉴了一下hahalidaxin的博客……了解了思路,但是莫名Wa了:最后再找了一篇dwtfukgv的博客才做出来
- 【杂题总汇】UVa-10618 Tango Tango Insurrection
[UVa-10618] Tango Tango Insurrection ◇ 题目 +vjudge 链接+ (以下选自<算法竞赛入门经典>-刘汝佳,有删改) <题目描述> 你想 ...
- sql的使用
1.自动获取最新订单号 select concat('XJDD',DATE_FORMAT(now(),'%Y%m%d'), LPAD(( FOR )) , max(SUBSTRING(inquiryn ...
- (三)Swagger配置多项目共用
重构了多个项目后,在联调接口时,查看api会发现Swagger在几个项目可用,有几个不可用,配置都一样,扫描也充分,那问题出在哪里呢?先仔细找了下Docket的源码,发现有这么个方法: /** * P ...
- 【转载】VS2015 + EF6连接MYSQL5.6
引用文章:https://jingyan.baidu.com/article/ce09321b9cc43f2bff858fbf.html 安装包注意点说明: 1.程序名称:mysql-for-visu ...
- 为什么 redis 单线程却能支撑高并发
redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 这个是问 redis 的时候,最基本的问题吧,redis 最基本的一个内部原理 ...
- php结合redis实现高并发下的抢购、秒杀功能【转】
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- 生产-消费模式的synchronized和lock实现(十)
lock: package com.net.thread.lock; import java.util.concurrent.locks.Condition; import java.util.con ...