题目描述

输入

第一行有四个整数 n, p, k, r,所有整数含义见问题描述。
1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1

输出

一行一个整数代表答案。

样例输入

2 10007 2 0

样例输出

8


题目大意

问从nk个数中选出若干个,且选出数的数目mod k=r的方案数

题解

dp+快速幂/矩阵乘法

题目描述是骗人的,一个一个加根本不可能加的过来。

关于矩阵乘法的题解可以参考 popoqqq大爷的博客 ,时间复杂度为O(k^3logn),

我的做法是dp+快速幂。

(UPD:后来知道这其实就是循环矩阵乘法)

设 $f[i][j]$ 表示从 $i$ 个数中选出若干个,且选出的数的数目 $\text{mod} k=j$ 的方案数

那么有 $f[i1+i2][j]=\sum((j1+j2)mod k = j)f[i1][j1]∗f[i2][j2]$

这里可能比较难用数学语言表述,但事实上其中的求和符号仅是对于 $j1$ 和 $j2$ ,并不对于 $i1$ 和 $i2$ ,也就是说只要找到任意一组 $i1$ 和 $i2$ ,就可以用 $f[i1]$ 和 $f[i2]$ 推出。

发现这一点类似于乘方,于是我们可以使用快速幂的方法来快速推出f[nk]数组,时间复杂度为O(k^2logn).

注意一下这里k可能等于1,所以初始化时不能简单地将f[0][1]赋为1,而是将f[0][1%k]加上1。

#include <cstdio>
#include <cstring>
typedef long long ll;
int p , k;
struct data
{
ll f[60];
data()
{
memset(f , 0 , sizeof(f));
}
data operator*(const data a)const
{
int i , j;
data tmp;
for(i = 0 ; i < k ; i ++ )
for(j = 0 ; j < k ; j ++ )
tmp.f[(i + j) % k] = (tmp.f[(i + j) % k] + f[i] * a.f[j]) % p;
return tmp;
}
}ans;
data pow(data x , ll y)
{
data ans;
ans.f[0] = 1;
while(y)
{
if(y & 1) ans = ans * x;
x = x * x , y >>= 1;
}
return ans;
}
int main()
{
int n , r;
scanf("%d%d%d%d" , &n , &p , &k , &r);
ans.f[0] ++ , ans.f[1 % k] ++ ;
printf("%lld\n" , pow(ans , (ll)n * k).f[r]);
return 0;
}

【bzoj4870】[Shoi2017]组合数问题 dp+快速幂/矩阵乘法的更多相关文章

  1. [BZOJ4870][Shoi2017]组合数问题 dp+矩阵乘

    4870: [Shoi2017]组合数问题 Time Limit: 10 Sec  Memory Limit: 512 MB Description Input 第一行有四个整数 n, p, k, r ...

  2. [luogu P1962] 斐波那契数列(带快速幂矩阵乘法模板)

    题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...

  3. 【BZOJ4870】组合数问题(动态规划,矩阵快速幂)

    [BZOJ4870]组合数问题(动态规划,矩阵快速幂) 题面 BZOJ 洛谷 题解 显然直接算是没法做的.但是要求的东西的和就是从\(nk\)个物品中选出模\(k\)意义下恰好\(r\)个物品的方案数 ...

  4. 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式

    矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b     *     A B   =   a*A+b*C  a*c+b*D c d     ...

  5. hdu_2604Queuing(快速幂矩阵)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604 Queuing Time Limit: 10000/5000 MS (Java/Others)  ...

  6. Number Sequence(快速幂矩阵)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 Number Sequence Time Limit: 2000/1000 MS (Java/O ...

  7. 快速幂 & 矩阵快速幂

    目录 快速幂 实数快速幂 矩阵快速幂 快速幂 实数快速幂 普通求幂的方法为 O(n) .在一些要求比较严格的题目上很有可能会超时.所以下面来介绍一下快速幂. 快速幂的思想其实是将数分解,即a^b可以分 ...

  8. bzoj4870: [Shoi2017]组合数问题(DP+矩阵乘法优化)

    为了1A我居然写了个暴力对拍... 那个式子本质上是求nk个数里选j个数,且j%k==r的方案数. 所以把组合数的递推式写出来f[i][j]=f[i-1][j]+f[i-1][(j-1+k)%k].. ...

  9. BZOJ4870 [六省联考2017] 组合数问题 【快速幂】

    题目分析: 构造f[nk][r]表示题目中要求的东西.容易发现递推公式f[nk][r]=f[nk-1][r]+f[nk-1][(r-1)%k].矩阵快速幂可以优化,时间复杂度O(k^3logn). 代 ...

随机推荐

  1. Win10下安装zookeeper

    Win10下安装zookeeper 注册中心zookeeper的安装 0.去Apache官网下载zookeeper http://zookeeper.apache.org/ 2.找到解压路径的conf ...

  2. 爬虫学习(十五)——json解析

    json与jsonpath 对象{}:jsonobject 对象:对象在js中表现为{}括起来的内容,数据结构为{key:value,key:value...}键值对的结构,在面向对象的结构中,key ...

  3. Centos下使用Docker部署asp.net core项目

    本文讲述 CentOS 系统 Docker 中部署 asp.net core开源项目 abp 的过程 步骤 1. 拉取 asp.net core 基础镜像 docker pull microsoft/ ...

  4. .NET 客户IP地址捕捉

    MVC模式下要获取客户IP可以在ActionFilterAttribute中进行拦截 filterContext.HttpContext.Request.UserHostAddress 同样,在Web ...

  5. JAVA / MySql 编程—— 第四章 高级查询(二)

    1.        EXISTS和NOT EXISTS子查询:EXISTS关键字用来检测数数据库对象是否存在.                  ★EXISTS和NOT EXISTS的结果只取决于是否 ...

  6. php动态画图

    index.php <?php $width=800; $height=600; //绘图技术 基本步骤 前提:在php.ini文件中启用gd库 //创建画布 默认背景是黑色的 $img=ima ...

  7. XStream 工具类 [ XmlUtil ]

    pom.xml <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId> ...

  8. xml的应用与dtd约束

    1.xml的应用 *不同的系统之间的传输数据(qq消息传输) *用来表示生活中有关系的数据(省市区的包含关系) *经常用在文件配置 **比如现在连接数据库,肯定知道数据库的名称和密码及用户名.    ...

  9. python之微信自动发送消息

    代码如下: from __future__ import unicode_literals from threading import Timer from wxpy import * import ...

  10. python flask豆瓣微信小程序案例

    项目步骤 定义首页模板index.html <!DOCTYPE html> <html lang="en"> <head> <meta c ...