@hdu - 6372@ sacul
@description@
定义矩阵 \(A_i\) 是一个大小为 \(p^i*p^i\) 的矩阵,其中 \(p\) 是第 \(c\) 个素数(c 给定),且 \(A_i[x][y] = [C(x, y) \mod p > 0]\)(其中 C(x, y) 是组合数)。
行列从 0 开始计数。
再定义 \(F[i][j]\) 表示 \((A_i)^j\) 中所有元素之和。
求 \(\sum_{i=1}^n\sum_{j=1}^{k}F[i][j]\)。对 10^9 + 7 取模。
Input
第一行包含一个整数 T,然后接下来是 T 组数据:
每一组数据包含三个整数 c, n, k (0 < n ≤ 10^9, 0 < c, k ≤ 10^5)。意义如上。
Output
对于每组数据,输出一个整数表示答案。
Sample Input
1
1 1 1
Sample Output
3
@solution@
看上去这个题非常不可做,先定义了一个矩阵,然后又要求矩阵幂,然后又要把这个矩阵幂中所有元素求和,然后又要把这些矩阵求和的结果再求和。
但是你只需要找到突破口,剩下的部分就一气呵成(其实一气呵成这个词不能这么用。。。今年中考考了这玩意儿,然后做错了,所以印象深刻。。。)
怎么找突破口?你只需要把题目倒过来读注意到矩阵的定义涉及到组合数对素数取模,于是就可以牵扯出 lucas 定理。
lucas 定理是什么?其实很简单。对于 \(C(n, m) \mod p\),我们将 n, m 拆成 p 进制数的形式,即 \(n = n_0 + n_1*p^1 + ..., m = m_0 + m_1*p^1 + ...\)。
于是 lucas 定理告诉我们:\(C(n, m) = C(n_0, m_0)*C(n_1, m_1)*... \mod p\)
证明这个定理也不难,只是与这道题无关所以暂且不提。
很显然 \(C(n, m) \mod p \ge 0\),所以我们只需要判断 \(C(n, m) \mod p = 0\) 是否成立即可。
又因 \(n_i < p, m_i < p\) (因为是 p 进制嘛),所以 \(C(n_i, m_i)\) 不可能含因子 p,故我们只需要对于每一个 i 判断是否 \(C(n_i, m_i) = 0\),而前面那个等价于 \(n_i > m_i\)。
所以 \(A_i[x][y]\) 为 1 等价于在 p 进制下 x 的每一位都 ≤ y 的对应位。
现在考虑 \((A_i)^j[x][y]\) 怎么求。
先试着考虑 \((A_i)^2[x][y]\),可以发现 \((A_i)^2[x][y] = \sum_{z}A_i[x][z]*A_i[z][y]\),只有当 \(A_i[x][z], A_i[z][y]\) 都为 1 时才会产生贡献。
这有点儿像偏序的关系,因为有些传递性和偏序形成链的感觉在里面。
或者用图论的语言,如果 \(A_i[x][y] = 1\) 则 x 向 y 连边。则 \((A_i)^2[x][y]\) 则有点儿像走两步(中途可以停留在原地)从 x 到达 y 的方案数。
从而简单推广,可以得到 \((A_i)^j[x][y]\) 表示走 j 步从 x 到达 y 的方案数。
那么 F[i][j] 的含义是什么?为了计数的方便我们暂且不用图论的语言描述。
F[i][j] 表示长度为 i 的 p 进制的数字串,选出 j+1 个记为 s0, s1, ... sj,对于第 x 位(1≤x≤n)始终满足 s0[x] ≤ s1[x] ≤ ... ≤ sj[x] 的方案总数。
怎么求 F[i][j] 呢?其实也比较简单。因为每一位都是独立的,所以考虑某一位然后乘法原理乘起来即可。
我们发现如果确定了 s0[x], s1[x], ..., sj[x] 分别是哪些数,它们的顺序始终是一定的(即排序过后的顺序)。所以我们相当于是求 x1 + ... + xp = j + 1 的非负整数解的个数。经典的组合数学问题,答案为 C(j+p, j+1)。
于是 F[i][j] = C(j+p, j+1)^i。
于是 \(\sum_{i=1}^n\sum_{j=1}^{k}F[i][j] = \sum_{i=1}^n\sum_{j=1}^{k}C(j+p, j+1)^i = \sum_{j=1}^{k}\sum_{i=1}^nC(j+p, j+1)^i\)。
枚举 j 然后等比数列求和即可。
注意 C(j+p, j+1) 与 C(j+p+1, j+1+1) 之间实际上是有倍数的关系(你可以把它们拆成阶乘形式以观察到这一点)。于是我们可以直接递推而不用预处理阶乘。
@accepted code@
#include<cstdio>
const int MAXM = 1299709;
const int MOD = int(1E9) + 7;
int pow_mod(int b, int p) {
int ret = 1;
while( p ) {
if( p & 1 ) ret = 1LL*ret*b%MOD;
b = 1LL*b*b%MOD;
p >>= 1;
}
return ret;
}
int prm[MAXM + 5], pcnt;
bool nprm[MAXM + 5];
void init() {
for(int i=2;i<=MAXM;i++) {
if( !nprm[i] )
prm[++pcnt] = i;
for(int j=1;1LL*i*prm[j]<=MAXM;j++) {
nprm[i*prm[j]] = true;
if( i % prm[j] == 0 )
break;
}
}
}
int solve(int p, int n, int k) {
int ans = 0, tmp = p;
for(int j=1;j<=k;j++) {
tmp = 1LL*tmp*(j + p)%MOD*pow_mod(j + 1, MOD - 2)%MOD;
if( tmp == 1 )
ans = (ans + n)%MOD;
else ans = (ans + 1LL*(pow_mod(tmp, n + 1) - 1)*pow_mod(tmp - 1, MOD-2)%MOD - 1)%MOD;
}
return (ans + MOD)%MOD;
}
int main() {
init();
int T; scanf("%d", &T);
for(int i=1;i<=T;i++) {
int c, n, k; scanf("%d%d%d", &c, &n, &k);
printf("%d\n", solve(prm[c], n, k));
}
}
@details@
似乎总喜欢废话很多。。。明明一个不是很复杂的题目却写了这么多东西。。。
这道题有一个点就是:等比数列要特判公比为 1 的情况。
。。。虽然数学上经常考这个东西,不过还是没记住。。。
@hdu - 6372@ sacul的更多相关文章
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 3791二叉搜索树解题(解题报告)
1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...
- hdu 4329
problem:http://acm.hdu.edu.cn/showproblem.php?pid=4329 题意:模拟 a. p(r)= R'/i rel(r)=(1||0) R ...
随机推荐
- Spring boot随时获取ApplicationContex
@Service public class SpringManager implements ApplicationListener<ContextRefreshedEvent> { pr ...
- java-异常进阶-包的使用
一 finally 1.1 异常执行的顺序 package test; public class Test { public static void main(String[] args) { Dem ...
- codevs1214 线段覆盖
1214 线段覆盖 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定x轴上的N(0<N<100)条线段, ...
- NOIP模拟 6.26
T1 子矩阵 题目描述 小A有一个N×M的矩阵,矩阵中1~N*M这(N*M)个整数均出现过一次.现在小A在这个矩阵内选择一个子矩阵,其权值等于这个子矩阵中的所有数的最小值.小A想知道,如果他选择的子矩 ...
- web前端开发必备技术
1.Vue.js是什么? Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注 ...
- QT生成GUID
#include <QCoreApplication> #include <QUuid> #include <QDebug> int main(int argc, ...
- go struct 继承
- No.5 Verilog 建模方式
5-1 门级建模 VerilogHDL内建基元门: 多输入门:and, nand, or, nor, xor, xnor; 多输出门:buf, not 三态门:bufif0, bufif1, noti ...
- 地不安装Oracle,plsql远程连接数据库
由于Oracle的庞大,有时候我们需要在只安装Oracle客户端如plsql.toad等的情况下去连接远程数据库,可是没有安装Oracle就没有一切的配置文件去支持.最后终于发现一个很有效的方法,Or ...
- TRS OM error
http://192.168.1.1/ http://tplogin.cn/admin888 wddqaz123456789 package="com.trs.om.bean" m ...