题目描述

为了揭穿$SERN$的阴谋,$Itaru$黑进了$SERN$的网络系统。
然而,想要完全控制$SERN$,还需要知道管理员密码。$Itaru$从截获的信息中发现,$SERN$的管理员密码是两个整数$l,s,0\leqslant s\leqslant l$,并且一旦得知了管理员密码,就可以生成出$SERN$各个网路接口的密码:各个网络接口的密码均是若干个长为$l$的$0/1$串,且每个串中$1$的个数恰为$s$。不难发现,生成的密码串个数是一个组合数。
$SERN$的网络系统是由$p^k$个网络接口构成的,$SERN$为了保证网络系统的稳定性,保证了$p$为质数,且所有生成的密码串个数能被$p^k$整除。为了网络通讯的方便,$SERN$的网络接口的密码不会太长,即可以保证$l\leqslant N$。
作为一名$Super\ Hacker$,$Itaru$已经想到了破解密码的绝妙方法,然而在这之前,他需要确认管理员密码的可能情况有多少。由于答案可能很大,答案对${10}^9+7$取模。


输入格式

仅包含一行三个整数$N,p,k$。


输出格式

仅包含一个整数,表示答案。


样例

样例输入:

4 2 2

样例输出:

2


数据范围与提示

样例解释:

有$2$种可能的情况,$l=4,s=1;l=4s=3$。

数据范围:

保证$1\leqslant p,k\leqslant {10}^9,1\leqslant N\leqslant {10}^{1000}$,$p$为质数。
各个测试点还满足如下约束:


题解

又是数学题,那就化式子。

组合数与阶乘有关,我们可以先考虑阶乘。
对于$n!$,满足$p^k|n!$的最大的$k$为:$$maxk=\sum \limits_{i=1}^{\infty}\left \lfloor \frac{n}{p^i}\right \rfloor$$
那么对于$C_n^m$,由于$C_n^m=\frac{n!}{m!(n-m)!}$,满足$p^k|C_n^m$的最大的$k$为:$$maxk=\sum \limits_{i=1}^{\infty}\left \lfloor \frac{n}{p^i}\right \rfloor-\left \lfloor \frac{m}{p^i}\right \rfloor-\left \lfloor \frac{n-m}{p^i}\right \rfloor \left \lfloor \frac{n-m}{p^i}\right \rfloor$$

然后我们引入一个新的名词:库默尔定理。

那么,什么是库默尔定理呢?

设$m,n$为正整数,$p$为素数,则$C_{m+n}^m$含$p$的幂次等于$m+n$在$p$进制下的进位次数。

下面给出证明:

组合数$C_{n+m}^m$所含$p$的幂次数为:$$\sum \limits_{i=1}^{\infty}\left \lfloor \frac{m+n}{p^i}\right \rfloor-\sum \limits_{i=1}^{\infty}\left \lfloor \frac{n}{p^i}\right \rfloor-\sum \limits_{i=1}^{\infty}\left \lfloor \frac{m}{p^i}\right \rfloor \\ =\sum \limits_{i=1}^{\infty}(\left \lfloor \frac{m+n}{p^i}\right \rfloor-\left \lfloor \frac{n}{p^i}\right \rfloor-\left \lfloor \frac{m}{p^i}\right \rfloor)$$

这是因为组合数公式$C_{n+m}^n=\frac{(n+m)!}{n!m!}$以及$n!$含有素数$p$的幂次公式$vp(n!)=\sum \limits_{i=1}^{\infty} \left \lfloor \dfrac{n}{p^i}\right \rfloor$。

对于某个$p^i$,$\left \lfloor \frac{m}{p^i}\right \rfloor$等于$m$在$p$进制表示下去掉后$i$位,在第$i+1$位上,$n+m$在这一位上进位的充要条件是$$\left \lfloor \frac{n+m}{p^i}\right \rfloor-\left \lfloor \frac{n}{p^i}\right \rfloor-\left \lfloor \frac{m}{p^i}\right \rfloor=1$$不进位则$$\left \lfloor \frac{n+m}{p^i}\right \rfloor-\left \lfloor \frac{n}{p^i}\right \rfloor-\left \lfloor \frac{m}{p^i}\right \rfloor=0$$因此$\sum \limits_{i=1}^{\infty}(\left \lfloor \frac{m+n}{p^i}\right \rfloor-\left \lfloor \frac{n}{p^i}\right \rfloor-\left \lfloor \frac{m}{p^i}\right \rfloor)$就是$n+m$在$p$进制下的进位次数。

那么题目所求便是两个和不超过$N$的正整数,它们在$p$进制下做加法近位了至少$k$的可能方案数。

那么考虑数位$DP$,设$dp[i][j][0/1][0/1]$表示到了$p$进制下的第$i$位,进位次数为$j$,下一位是否进位,前$i$位是否与$N$在$p$进制下相同的方案。

时间复杂度:$\Theta(S^2)$设$S$为$N$在$p$进制下的位数。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
char ch[1001];
long long N[1001],S[1001];
long long p,k;
long long dp[1001][1001][2][2];
long long ans;
int main()
{
scanf("%s%lld%lld",ch+1,&p,&k);
N[0]=strlen(ch+1);
for(int i=1;i<=N[0];i++)N[i]=ch[i]-'0';
for(int i=1;(i<<1)<=N[0];i++)
N[i]^=N[N[0]-i+1]^=N[i]^=N[N[0]-i+1];
while(N[0])
{
for(int i=N[0];i;i--)
{
if(i>1)N[i-1]+=N[i]%p*10;
else S[++S[0]]=N[i]%p;
N[i]/=p;
}
while(N[0]&&!N[N[0]]){N[0]--;if(N[0]<0){puts("0");return 0;}}
}
dp[0][0][0][0]=1;
for(int i=1;i<=S[0];i++)
for(int j=0;j<=i;j++)
{
dp[i][j][0][0]=(((S[i]+1)*(S[i]+2)>>1)%1000000007*dp[i-1][j][0][0]%1000000007+(S[i]*(S[i]+1)>>1)%1000000007*(dp[i-1][j][0][1]+dp[i-1][j][1][0])%1000000007+(S[i]*(S[i]-1)>>1)%1000000007*dp[i-1][j][1][1]%1000000007)%1000000007;
dp[i][j+1][0][1]=((((p<<1)-S[i]-2)*(S[i]+1)>>1)%1000000007*dp[i-1][j][0][0]%1000000007+(((p<<1)-S[i])*(S[i]+1)>>1)%1000000007*dp[i-1][j][0][1]%1000000007+(((p<<1)-S[i]-1)*S[i]>>1)%1000000007*dp[i-1][j][1][0]%1000000007+(((p<<1)-S[i]+1)*S[i]>>1)%1000000007*dp[i-1][j][1][1]%1000000007)%1000000007;
dp[i][j][1][0]=(((S[i]+p+2)*(p-S[i]-1)>>1)%1000000007*dp[i-1][j][0][0]%1000000007+((p+S[i])*(p-S[i]-1)>>1)%1000000007*dp[i-1][j][0][1]%1000000007+((p+S[i]+1)*(p-S[i])>>1)%1000000007*dp[i-1][j][1][0]%1000000007+((p+S[i]-1)*(p-S[i])>>1)%1000000007*dp[i-1][j][1][1]%1000000007)%1000000007;
dp[i][j+1][1][1]=(((p-S[i]-2)*(p-S[i]-1)>>1)%1000000007*dp[i-1][j][0][0]%1000000007+((p-S[i])*(p-S[i]-1)>>1)%1000000007*(dp[i-1][j][0][1]+dp[i-1][j][1][0])%1000000007+((p-S[i]+1)*(p-S[i])>>1)%1000000007*dp[i-1][j][1][1]%1000000007)%1000000007;
}
for(int i=k;i<=S[0];i++)
ans=(ans+dp[S[0]][i][0][0])%1000000007;
printf("%lld",ans);
return 0;
}

rp++

[CSP-S模拟测试]:密码(数位DP+库默尔定理)的更多相关文章

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

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

  2. [CSP-S模拟测试]:密码(AC自动机+DP)

    题目传送门(内部题19) 输入格式 第一行两个正整数$n,k$,代表秘钥个数和要求.接下来两个正整数$x$和$y$,意义如题所述.接下来$n$行,每行一个正整数,意义如题所述. 输出格式 一个正整数, ...

  3. 2018.06.26 NOIP模拟 号码(数位dp)

    题目背景 SOURCE:NOIP2015-GDZSJNZX(难) 题目描述 Mike 正在在忙碌地发着各种各样的的短信.旁边的同学 Tom 注意到,Mike 发出短信的接收方手机号码似乎都满足着特别的 ...

  4. 2018.08.18 NOIP模拟 game(数位dp)

    Game 题目背景 SOURCE:NOIP2015-SHY4 题目描述 Alice 和 Bob 正在玩一个游戏,两个人从 1 轮流开始报数,如果遇到 7 的倍数或者遇到的这个数的十进制表示中含 7 , ...

  5. [bzoj3209][花神的数论题] (数位dp+费马小定理)

    Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了. ...

  6. scauoj 18025 小明的密码 数位DP

    18025 小明的密码 时间限制:4000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description 小明的密码由N(1<=N& ...

  7. [CSP-S模拟测试]:B(DP+数学)

    题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...

  8. [CSP-S模拟测试]:蛇(DP+构造+哈希)

    题目传送门(内部题140) 输入格式 前两行有两个长度相同的字符串,描述林先森花园上的字母. 第三行一个字符串$S$. 输出格式 输出一行一个整数,表示有多少种可能的蛇,对$10^9+7$取模. 样例 ...

  9. [CSP-S模拟测试]:最小值(DP+乱搞)

    题目背景 $Maxtir$更喜欢序列的最小值. 题目传送门(内部题128) 输入格式 第一行输入一个正整数$n$和四个整数$A,B,C,D$. 第二行输入$n$个整数,第$i$个数表示$a_i$. 输 ...

随机推荐

  1. List 集合 一行4个排序

    List<string> list = new List<string>(); ; i < ; i++) { list.Add(i.ToString()); } int ...

  2. C# 常用类库说明

    Array类 用括号声明数组是C#中使用Array类的记号.在后台使用C#语法,会创建一个派生于抽象基类Array的新类.这样,就可以使用Array类为每个C#数组定义的方法和属性了. Array类实 ...

  3. H.264 详解

    一.MPEG-4说明 1.VOP视频编码技术 VO(Video Object):视频对象,它是场景中的某个物体,最简单的情况下就是矩形框,它是有生命期的,由时间上连续的许多帧构成. VOP(Video ...

  4. CF516D Drazil and Morning Exercise

    cf luogu 首先每个点到最远点的距离可以预处理出来,这个距离显然是这个点到树直径两端点的最大值.把那个距离记为\(d_i\),然后从小到大枚举\(d_i\),并强制它为最大的\(d_i\),那么 ...

  5. postgresql与mysql 优缺点

    MySQL的主要优点 (速度,流行,window,线程,事务) 1. 首先是速度,MySQL通常要比PostgreSQL快得多.MySQL自已也宣称速度是他们追求的主要目标之一,基于这个原因,MySQ ...

  6. 第十一章、特性property

    目录 第十一章.特性property 一.property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 二.为什么要用property 三.封装与拓展性 第十一章.特性property ...

  7. Delphi WaitCommEvent函数

  8. 利用openssl完成自签发证书步骤--精华版

    #CentOS 7 CA目录 cd /etc/pki/CA #建立 demoCA 目录结构mkdir -p ./demoCA/{private,newcerts}touch ./demoCA/inde ...

  9. gyp ERR! stack Error: EACCES: permission denied, mkdir问题解决方案

    sudo npm i --unsafe-perm 原因还是权限问题 就是说 npm 出于安全考虑不支持以 root 用户运行,即使你用 root 用户身份运行了,npm 会自动转成一个叫 nobody ...

  10. Arm汇编指令集2

    什么是协处理器: SoC内部另一处理核心,协助CPU实现某些功能,被主CPU调用执行一定任务. ARM设计上支持16个协处理器,但是一般SoC只实现其中的CP15(cp就是cooperation pr ...