Codeforces 题目传送门 & 洛谷题目传送门

一道数论与数位 dp 结合的神题 %%%

首先在做这道题之前你需要知道一个定理:对于质数 \(p\) 及 \(n,k\),最大的满足 \(p^{\alpha}\mid\dbinom{n}{k}\) 的 \(\alpha\) 为 \(k\) 与 \(n-k\) 在 \(p\) 进制下相加的进位次数。证明就考虑扩展 Lucas 定理,记 \(f(x)\) 为最大的满足 \(p^{\alpha}\mid x\) 的 \(\alpha\),那么由 \(\dbinom{n}{k}=\dfrac{n!}{k!(n-k)!}\) 可知 \(f(\dbinom{n}{k})=f(n!)-f(k!)-f((n-k)!)\),我们考虑将 \(k,n-k\) 都在 \(k\) 进制下表示,我们设它们从高到低分别是 \(k=(a_{m-1}a_{m-2}\cdots a_1a_0)_p,n-k=(b_{m-1}b_{m-2}\cdots b_1b_0)_p,n=(c_{m-1}c_{m-2}\cdots c_1c_0)_p\)(在这里,我们不妨假设 \(n<p^m\),即 \(n+k\) 在 \(p^m\) 位不会产生进位),那么根据扩展 Lucas 定理 \(f(k!)\) 应当为 \(\sum\limits_{i=1}^{m-1}(a_{m-1}a_{m-2}\cdots a_i)_p\),即 \(k\) 在 \(p\) 进制表示下所有前缀(不包括本身)表示的数之和。很显然的一点是对于任意 \(i\in[1,m-1]\),\((a_{m-1}a_{m-2}\cdots a_i)_p+(b_{m-1}b_{m-2}\cdots b_i)_p\le(c_{m-1}c_{m-2}\cdots c_i)_p\),那么什么时候 \((a_{m-1}a_{m-2}\cdots a_i)_p+(b_{m-1}b_{m-2}\cdots b_i)_p<(c_{m-1}c_{m-2}\cdots c_i)_p\) 呢?显然如果前面没有进位那就不可能存在这种情况,否则,由于只有两数相加,因此最多进上来一位,而进上来一位以后显然就有 \((a_{m-1}a_{m-2}\cdots a_i)_p+(b_{m-1}b_{m-2}\cdots b_i)_p+1=(c_{m-1}c_{m-2}\cdots c_i)_p\),会对答案产生 \(1\) 的贡献,因此该结论成立。据说该结论有一个名字叫什么库默尔(Kummer)定理,不过名字啥的不重要啦((

知道这个结论之和就可以数位 dp 了。题目中 \(\alpha\le 10^9\) 是假的,如果 \(\alpha>\log_pA\) 那答案显然为 \(0\)。我们首先将题目给出的那个数用 \(p\) 进制表示,我们设 \(dp_{i,j,0/1,0/1}\) 表示考虑了最高的 \(i\) 位,当前进位了 \(j\) 次,上一位(第 \(i+1\) 高的位)是否产生进位,当前是否达到上界,考虑转移,假设 \(A\) 的第 \(i+1\) 位的值为 \(c\),我们要决策 \(k\) 的第 \(i+1\) 位的值 \(a\) 与 \(n-k\) 的第 \(i+1\) 位的值 \(b\),那么有转移:

  • \(dp_{i+1,j,0,0}\):

    • 如果从 \(dp_{i,j,0,0}\) 转移来那么需满足 \(a+b<p\),方案数 \(\dfrac{p(p+1)}{2}\)
    • 如果从 \(dp_{i,j,0,1}\) 转移来那么需满足 \(a+b<c\),方案数 \(\dfrac{c(c+1)}{2}\)
    • 如果从 \(dp_{i,j,1,0}\) 转移来那么需满足 \(a+b\ge p\),方案数 \(\dfrac{p(p-1)}{2}\)
    • 如果从 \(dp_{i,j,1,1}\) 转移来那么需满足 \(p\le a+b<p+c\),方案数 \(\dfrac{(p+c)(p+c+1)}{2}-\dfrac{p(p+1)}{2}=\dfrac{c(2n-c-1)}{2}\)
  • \(dp_{i+1,j,0,1}\):
    • 如果从 \(dp_{i,j,0,1}\) 转移来那么需满足 \(a+b=c\),方案数 \(c+1\)
    • 如果从 \(dp_{i,j,1,1}\) 转移来那么需满足 \(a+b=p+c\),方案数 \(p-c-1\)
  • \(dp_{i+1,j,1,0}\):
    • 如果从 \(dp_{i,j,0,0}\) 转移来那么需满足 \(a+b<p-1\),方案数 \(\dfrac{p(p-1)}{2}\)
    • 如果从 \(dp_{i,j,0,1}\) 转移来那么需满足 \(a+b<c-1\),方案数 \(\dfrac{c(c-1)}{2}\)
    • 如果从 \(dp_{i,j,1,0}\) 转移来那么需满足 \(a+b\ge p-1\),方案数 \(\dfrac{p(p+1)}{2}\)
    • 如果从 \(dp_{i,j,1,1}\) 转移来那么需满足 \(p\le a+b+1<p+c\),方案数 \(\dfrac{(p+c)(p+c-1)}{2}-\dfrac{p(p-1)}{2}=\dfrac{c(2n-c+1)}{2}\)
  • \(dp_{i+1,j,1,1}\):
    • 如果从 \(dp_{i,j,0,1}\) 转移来那么需满足 \(a+b+1=c\),方案数 \(c\)
    • 如果从 \(dp_{i,j,1,1}\) 转移来那么需满足 \(a+b+1=p+c\),方案数 \(p-c\)

算下贡献转移一下即可。时间复杂度 \(\mathcal O(\log^2_kA)\)。

最好使用滚动数组优化。

const int MAXL=4000;
const int MOD=1e9+7;
int n,alpha,len,m=0,a[MAXL+5],x[MAXL+5];
char A[MAXL+5];int dp[2][MAXL+5][2][2];
int main(){
scanf("%d%d%s",&n,&alpha,A+1);len=strlen(A+1);
if(alpha>MAXL) return puts("0"),0;
for(int i=1;i<=len;i++) a[len-i+1]=A[i]-'0';
while(len){
ll cur=0;
for(int i=len;i;i--){
cur=cur*10+a[i];a[i]=cur/n;cur%=n;
} x[++m]=cur;if(!a[len]) len--;
} int cur=1,pre=0;
dp[cur][0][0][1]=1;
for(int i=m;i;i--){
cur^=pre^=cur^=pre;
memset(dp[cur],0,sizeof(dp[cur]));
int c1=1ll*(n+1)*n/2%MOD;
int c2=1ll*(x[i]+1)*x[i]/2%MOD;
int c3=1ll*(n-1)*n/2%MOD;
int c4=1ll*x[i]*(n*2-x[i]-1)/2%MOD;
int c5=1ll*(x[i]-1)*x[i]/2%MOD;
int c6=1ll*x[i]*(n*2-x[i]+1)/2%MOD;
for(int j=0;j<=m-i+1;j++){
int f0=dp[pre][j][0][0],f1=dp[pre][j][0][1];
int f2=dp[pre][j][1][0],f3=dp[pre][j][1][1];
dp[cur][j][0][0]=(1ll*f0*c1+1ll*f1*c2+1ll*f2*c3+1ll*f3*c4)%MOD;
dp[cur][j][0][1]=(1ll*(x[i]+1)*f1+1ll*(n-x[i]-1)*f3)%MOD;
dp[cur][j+1][1][0]=(1ll*f0*c3+1ll*f1*c5+1ll*f2*c1+1ll*f3*c6)%MOD;
dp[cur][j+1][1][1]=(1ll*x[i]*f1+1ll*(n-x[i])*f3)%MOD;
}
} int ans=0;
for(int i=alpha;i<=m;i++){
ans=(ans+dp[cur][i][0][0])%MOD;
ans=(ans+dp[cur][i][0][1])%MOD;
} printf("%d\n",ans);
return 0;
}

Codeforces 582D - Number of Binominal Coefficients(Kummer 定理+数位 dp)的更多相关文章

  1. CF582D Number of Binominal Coefficients 库默尔定理 数位dp

    LINK:Number of Binominal Coefficients 原来难题都长这样.. 水平有限只能推到一半. 设\(f(x)\)表示x中所含p的最大次数.即x质因数分解之后 p的指标. 容 ...

  2. uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)

    uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...

  3. bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP

    1902: Zju2116 Christopher Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 172  Solved: 67[Submit][Stat ...

  4. Codeforces Beta Round #51 D. Beautiful numbers(数位dp)

    题目链接:https://codeforces.com/contest/55/problem/D 题目大意:给你一段区间[l,r],要求这段区间中可以整除自己每一位(除0意外)上的数字的整数个数,例如 ...

  5. 【XSY2691】中关村 卢卡斯定理 数位DP

    题目描述 在一个\(k\)维空间中,每个整点被黑白染色.对于一个坐标为\((x_1,x_2,\ldots,x_k)\)的点,他的颜色我们通过如下方式计算: 如果存在一维坐标是\(0\),则颜色是黑色. ...

  6. BZOJ4737 组合数问题(卢卡斯定理+数位dp)

    不妨不管j<=i的限制.由卢卡斯定理,C(i,j) mod k=0相当于k进制下存在某位上j大于i.容易想到数位dp,即设f[x][0/1][0/1][0/1]为到第x位时是否有某位上j> ...

  7. BZOJ4591 SHOI2015超能粒子炮·改(卢卡斯定理+数位dp)

    注意到模数很小,容易想到使用卢卡斯定理,即变成一个2333进制数各位组合数的乘积.对于k的限制容易想到数位dp.可以预处理一发2333以内的组合数及组合数前缀和,然后设f[i][0/1]为前i位是否卡 ...

  8. codeforces 597div2 F. Daniel and Spring Cleaning(数位dp+二维容斥)

    题目链接:https://codeforces.com/contest/1245/problem/F 题意:给定一个区间(L,R),a.b两个数都是属于区间内的数,求满足 a + b = a ^ b ...

  9. Codeforces 914C Travelling Salesman and Special Numbers:数位dp

    题目链接:http://codeforces.com/problemset/problem/914/C 题意: 对数字x进行一次操作,可以将数字x变为x在二进制下1的个数. 显然,一个正整数在进行了若 ...

随机推荐

  1. 分享一份软件测试项目实战(web+app+h5+小程序)

    大家好,我是谭叔. 本次,谭叔再度出马,给大家找了一个非常适合练手的软件测试项目,此项目涵盖web端.app端.h5端.小程序端,可以说非常之全面. 缘起 在这之前,谭叔已经推出了九套实战教程. 但是 ...

  2. UI自动化测试之Airtest

    官方文档: https://airtest.doc.io.netease.com/ 本文我们讲解下Airtest的使用,主要学习目标有以下几点: (1)认识Airtest (2)了解Airtest能做 ...

  3. MySQL:补充知识

    MySQL补充知识 在学习完 MySQL 基础与提高内容后: 基础知识笔记: MySQL:基础语法-1 MySQL:基础语法-2 MySQL:基础语法-3 MySQL:基础语法-4 提高知识笔记: M ...

  4. 机器学习:KNN

    KNN:K-nearst neighbors 简介: k-近邻算法采用测量不同特征值之间的距离来进行分类,简而言之为:人以类聚,物以群分 KNN既可以应用于分类中,也可用于回归中:在分类的预测是,一般 ...

  5. 团队任务拆解(alpha)

    团队任务拆解(alpha阶段) 项目 内容 班级:2020春季计算机学院软件工程(罗杰 任健) 博客园班级博客 作业:团队任务拆解 团队任务拆解 我们在这个课程中的目标 写出令客户和自己都满意的代码同 ...

  6. 【SDOI2014】数数(补)

    见 AC自动机(补坑了) [SDOI2014] 数数 简要题意:  我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为子串.例如当S={22,333,0233}时 ...

  7. 该如何有效的提高C/C++语言编程能力

    很多答案都谈到算法的重要性,我的答案主要集中在C++上,只是一些个人经验. 其实我以前也有这样的困惑,感觉完了不知道怎么用.而且我也不是学计算机的,也没有从事相关工作,所以大概有十年的时间都没写什么程 ...

  8. T-SQL——函数——时间操作函数

    目录 0. 日期和时间类型 0.0 时间类型 1. 转换函数 1.1 CAST 1.2 CONVERT 2. 日期操作函数 2.0 GETDATE和GETUTCDATE 2.1 SYSDATETIME ...

  9. 问题解决:补充安装c语言的库函数和系统调用man手册

    问题解决:补充安装c语言的库函数和系统调用man手册 ​ 今日份麻麻~上课时大家的Ubuntu都可以通过man查到关于stat的库函数,但是我的Kali查出来是这样: ​ 询问老师之后得知需要去安装相 ...

  10. Linux网卡bond模式

    Bond模式 交换机配置 mode=0 balance-rr 轮询均衡模式 LACP mode on 强制链路聚合 mode=1 active-backup 主备模式 无 mode=2 balance ...