Codeforces 582D - Number of Binominal Coefficients(Kummer 定理+数位 dp)
一道数论与数位 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)的更多相关文章
- CF582D Number of Binominal Coefficients 库默尔定理 数位dp
LINK:Number of Binominal Coefficients 原来难题都长这样.. 水平有限只能推到一半. 设\(f(x)\)表示x中所含p的最大次数.即x质因数分解之后 p的指标. 容 ...
- uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)
uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...
- bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP
1902: Zju2116 Christopher Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 172 Solved: 67[Submit][Stat ...
- Codeforces Beta Round #51 D. Beautiful numbers(数位dp)
题目链接:https://codeforces.com/contest/55/problem/D 题目大意:给你一段区间[l,r],要求这段区间中可以整除自己每一位(除0意外)上的数字的整数个数,例如 ...
- 【XSY2691】中关村 卢卡斯定理 数位DP
题目描述 在一个\(k\)维空间中,每个整点被黑白染色.对于一个坐标为\((x_1,x_2,\ldots,x_k)\)的点,他的颜色我们通过如下方式计算: 如果存在一维坐标是\(0\),则颜色是黑色. ...
- BZOJ4737 组合数问题(卢卡斯定理+数位dp)
不妨不管j<=i的限制.由卢卡斯定理,C(i,j) mod k=0相当于k进制下存在某位上j大于i.容易想到数位dp,即设f[x][0/1][0/1][0/1]为到第x位时是否有某位上j> ...
- BZOJ4591 SHOI2015超能粒子炮·改(卢卡斯定理+数位dp)
注意到模数很小,容易想到使用卢卡斯定理,即变成一个2333进制数各位组合数的乘积.对于k的限制容易想到数位dp.可以预处理一发2333以内的组合数及组合数前缀和,然后设f[i][0/1]为前i位是否卡 ...
- codeforces 597div2 F. Daniel and Spring Cleaning(数位dp+二维容斥)
题目链接:https://codeforces.com/contest/1245/problem/F 题意:给定一个区间(L,R),a.b两个数都是属于区间内的数,求满足 a + b = a ^ b ...
- Codeforces 914C Travelling Salesman and Special Numbers:数位dp
题目链接:http://codeforces.com/problemset/problem/914/C 题意: 对数字x进行一次操作,可以将数字x变为x在二进制下1的个数. 显然,一个正整数在进行了若 ...
随机推荐
- 如何再一台电脑上配置多个tomcat同时运行
1.配置运行tomcat 首先要配置java的jdk环境,这个就不在谢了 不懂去网上查查,这里主要介绍再jdk环境没配置好的情况下 如何配置运行多个tomcat 2.第一个tomcat: 找到&qu ...
- [软工顶级理解组] Alpha阶段测试报告
[软工顶级理解组] Alpha阶段测试报告 在测试过程中发现了多少Bug? 测试阶段发现并已修复的bug: 尚且存在,但是难以解决或者不影响使用的bug: 计算重修课程的时候,如果重修课程的课程号和原 ...
- Unity 3D手游对不同分辨率屏幕的UI自适应
目前安卓手机的屏幕大小各异,没有统一的标准,因此用Unity 3D制作的手游需要做好对不同分辨率屏幕的UI自适应,否则就会出现UI大小不一和位置错位等问题. 我们的项目在开发时的参照分辨率(Refer ...
- [敏捷软工团队博客]The Agiles 团队介绍&团队采访
项目 内容 课程:北航-2020-春-敏捷软工 博客园班级博客 作业要求 团队作业-团队介绍和采访 团队名称来源 The Agile is The Agile. 敏捷就是敏捷.我们只是敏捷的践行者罢了 ...
- 主仆见证了 Hobo 的离别 题解
前言: 题面挺神仙.反正我考试的时候看了40分钟也没看懂. 后来改题感觉自己写的挺假,没想到加个\(k==1\)的特判竟然就A了?无语力. 解析: 看懂题以后就好说了.首先这显然是一个树形结构.我们考 ...
- gdal3.1.0+VS2017+geos+kml编译总结
1.简介 gdal3.1.0编译过程中必须依赖proj,编译gdal必须要编译proj,proj的编译需要sqlite3,因此想要编译gdal3.1.0需要先编译proj和sqlite3 2.关于sq ...
- WPF PropertyChanged实现子属性通知
今天用WPF的View绑定了ViewModel的一个属性类,结果在属性类的子属性修改时,没有通知到UI. 如有要显示一个学生信息,采用WPF MVVM的模式,则前端代码 <StackPanel& ...
- CF #749
A 题意 有个长度为n的序列, 每个数互不相同, 求总和最大的最长子序列, 并输出每个i: 题解 emmmmmm, 刚开始看到这个数据和题解被迷惑了, 以为有什么顺序, 并且一直在想一些复杂度较高的算 ...
- Win10下C语言转8086汇编
目录 Win10下C语言转8086汇编 简介 开始 写C代码 转换成汇编代码 Win10下C语言转8086汇编 简介 最近学习<王爽汇编>,然后突发奇想,想一边写C语言用编译器将其翻译成汇 ...
- HTML bootstrap 模态对话框添加用户
HTML 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> ...