题目是要我们求出如下柿子:

\[\sum_{i=0}^{n}C_{nk}^{ik+r}
\]

考虑k和r非常小,我们能不能从这里切入呢?

如果你注意到,所有组合数上方的数\(\%k==r\),那么是不是可以从\(DP\)开始呢?

跟据上述性质,我们可以得到暴力\(DP\):

考虑组合数的实际意义是在n个数中选出m个,那么我们可以设\(dp[i][j]\)表示在i个元素中,选了\(m\%k==j\)的方案数

转移就可以用\(dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1]\)了,根据你的欧气,你可以获得\(45-70\)分的分数

由于空间原因,暴力代码用了滚动数组;由于文章长度原因,暴力代码省去了一些没必要的东西

\(Brute:\)

#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define drep(i, s, t) for(re int i = t; i >= s; -- i)
int n, m, p, r, dp[55];
int main() {
n = read(), p = read(), m = read(), r = read(), dp[0] = 1;
rep(i, 1, n * m) {
int pax = dp[m - 1];
drep(j, 1, m - 1) dp[j] = (dp[j - 1] + dp[j]) % p;
dp[0] = (dp[0] + pax) % p;
}
printf("%d", dp[r]);
return 0;
}

那么我们还可以怎么优化呢?

考虑到\(N*K\)达到了\(5*10^{10}\),我们考虑矩阵优化:

我们怎么从\(dp[i - 1][0……m-1]\)推出\(dp[i][0……m-1]\)呢?

只需要构造一个\(50*50\)的矩阵,第一行中第一列和最后一列为\(1\),其余第\(i\)行第\(i\)列和第\(i-1\)列为1,其他都是\(0\),问题便可以解决

注意,矩阵初始化的时候不能直接\(=1\),要考虑\(k=1\)的情况

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
#define rep(i, s, t) for(int i = s; i <= t; ++ i)
int n, m, p, r;
struct Martix {
int a[55][55];
void Init() { rep(i, 1, m) a[i][i] = 1; }
void Mem() { memset(a, 0, sizeof(a)); }
}Ans, Base;
Martix Mul(Martix a, Martix b) {
Martix c; c.Mem();
rep(i, 1, m) rep(j, 1, m) rep(k, 1, m) c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % p) % p;
return c;
}
Martix Pow(Martix a, int b) {
Martix R; R.Mem(), R.Init();
while(b) {
if(b & 1) R = Mul(R, a);
a = Mul(a, a), b >>= 1;
}
return R;
}
signed main() {
n = read(), p = read(), m = read(), r = read();
++ Base.a[1][1], ++ Base.a[1][m], ++ Ans.a[1][1];
rep(i, 2, m) ++ Base.a[i][i], ++ Base.a[i][i - 1];
Ans = Mul(Ans, Pow(Base, n * m));
printf("%lld", Ans.a[1][1 + r]);
return 0;
}

P3746 【[六省联考2017]组合数问题】的更多相关文章

  1. P3746 [六省联考2017]组合数问题

    P3746 [六省联考2017]组合数问题 \(dp_{i,j}\)表示前\(i\)个物品,取的物品模\(k\)等于\(r\),则\(dp_{i,j}=dp_{i-1,(j-1+k)\%k}+dp_{ ...

  2. 洛谷P3746 [六省联考2017]组合数问题

    题目描述 组合数 C_n^mCnm​ 表示的是从 n 个互不相同的物品中选出 m 个物品的方案数.举个例子,从 (1;2;3) 三个物品中选择两个物品可以有 (1;2);(1;3);(2;3) 这三种 ...

  3. [BZOJ4870][六省联考2017]组合数问题(组合数动规)

    4870: [Shoi2017]组合数问题 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 748  Solved: 398[Submit][Statu ...

  4. bzoj千题计划263:bzoj4870: [六省联考2017]组合数问题

    http://www.lydsy.com/JudgeOnline/problem.php?id=4870 80分暴力打的好爽 \(^o^)/~ 预处理杨辉三角 令m=n*k 要求满足m&x== ...

  5. 洛谷$P$3746 [六省联考2017]组合数问题 $dp$+矩乘+组合数学

    正解:$dp$+矩乘+组合数学 解题报告: 传送门! 首先不难发现这个什么鬼无穷就是个纸老虎趴,,,最多在$\binom{n\cdot k+r}{n\cdot k}$的时候就已经是0了后面显然不用做下 ...

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

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

  7. [六省联考2017]组合数问题 (矩阵优化$dp$)

    题目链接 Solution 矩阵优化 \(dp\). 题中给出的式子的意思就是: 求 nk 个物品中选出 mod k 为 r 的个数的物品的方案数. 考虑朴素 \(dp\) ,定义状态 \(f[i][ ...

  8. 六省联考2017 Day1

    目录 2018.3.18 Test T1 BZOJ.4868.[六省联考2017]期末考试 T2 T3 BZOJ.4870.[六省联考2017]组合数问题(DP 矩阵快速幂) 总结 考试代码 T1 T ...

  9. 【BZOJ4873】[六省联考2017]寿司餐厅(网络流)

    [BZOJ4873][六省联考2017]寿司餐厅(网络流) 题面 BZOJ 洛谷 题解 很有意思的题目 首先看到答案的计算方法,就很明显的感觉到是一个最大权闭合子图. 然后只需要考虑怎么构图就行了. ...

随机推荐

  1. JVM与并发

    1.jvm内存模型 硬件内存模型 处理器-->高速缓存-->缓存一致性协议-->主存 java内存模型 线程<-->工作内存<-->save和load < ...

  2. aop 打印请求信息

    项目中使用 AOP 打印请求信息,打印响应信息.package com.example.aspect; import com.alibaba.fastjson.JSON;import com.goog ...

  3. vs2013 C++编译器在调试的时候无法看到变量的值

  4. asp.net core 之中间件

    Http请求资源的过程可以看成一个管道:“Pipe”,并不是所有的请求都是合法的.安全的,其于功能.性能或安全方面的考虑,通常需要在这管道中装配一些处理程序来筛选和加工这些请求.这些处理程序就是中间件 ...

  5. iOS开发,导入c文件引发的Could not build module 'UIKit'问题

    导致出现异常的原因是是因为工程中添加了某(第三方开源库) 一般情况下出现“Unknown type name”是头文件互相引用出现的,这里可以排除,由于源码使用是c\c++与oc混编, 考虑新的XCo ...

  6. 【面试突击】- sql语句的优化分析

    开门见山,问题所在 原文地址:http://www.cnblogs.com/knowledgesea/p/3686105.html sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种 ...

  7. js流程控制语句(三)

    如果在语句中需要声明变量时:最好给他们赋予初始类型值[js中变量声明使用var属于弱类型声明,若只声明则均表示为undefined,在后面语句计算中可能会产生错误计算];相应的类型变量需要如下方式进行 ...

  8. 关于定义变量名为"name"的坑!!!

    昨天下午没有什么工作可做,闲来无事就上博客园看看了,有个问题让我一直很纳闷. 直接上代码吧: 再用表达式创建函数时遇到的问题,这里的代码按照正常逻辑只有那个在变量定义后面的函数执行打印的值才是&quo ...

  9. 英语caement水泥

    水泥石  又称净浆硬化体.是指 硬化后的水泥浆体,称为水泥石,在英语里是cement有时写作caement [1] ,是由胶凝体.未水化的水泥颗粒内核.毛细孔等组 成的非均质体. 中文名:水泥石 外 ...

  10. 【python】udp 数据的发送和接收

    import socket def send_message(): # 创建一个udp套接字 udp_socker = socket.socket(socket.AF_INET,socket.SOCK ...