[CSP-S模拟测试]:密码(数位DP+库默尔定理)
题目描述
为了揭穿$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+库默尔定理)的更多相关文章
- CF582D Number of Binominal Coefficients 库默尔定理 数位dp
LINK:Number of Binominal Coefficients 原来难题都长这样.. 水平有限只能推到一半. 设\(f(x)\)表示x中所含p的最大次数.即x质因数分解之后 p的指标. 容 ...
- [CSP-S模拟测试]:密码(AC自动机+DP)
题目传送门(内部题19) 输入格式 第一行两个正整数$n,k$,代表秘钥个数和要求.接下来两个正整数$x$和$y$,意义如题所述.接下来$n$行,每行一个正整数,意义如题所述. 输出格式 一个正整数, ...
- 2018.06.26 NOIP模拟 号码(数位dp)
题目背景 SOURCE:NOIP2015-GDZSJNZX(难) 题目描述 Mike 正在在忙碌地发着各种各样的的短信.旁边的同学 Tom 注意到,Mike 发出短信的接收方手机号码似乎都满足着特别的 ...
- 2018.08.18 NOIP模拟 game(数位dp)
Game 题目背景 SOURCE:NOIP2015-SHY4 题目描述 Alice 和 Bob 正在玩一个游戏,两个人从 1 轮流开始报数,如果遇到 7 的倍数或者遇到的这个数的十进制表示中含 7 , ...
- [bzoj3209][花神的数论题] (数位dp+费马小定理)
Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了. ...
- scauoj 18025 小明的密码 数位DP
18025 小明的密码 时间限制:4000MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC Description 小明的密码由N(1<=N& ...
- [CSP-S模拟测试]:B(DP+数学)
题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...
- [CSP-S模拟测试]:蛇(DP+构造+哈希)
题目传送门(内部题140) 输入格式 前两行有两个长度相同的字符串,描述林先森花园上的字母. 第三行一个字符串$S$. 输出格式 输出一行一个整数,表示有多少种可能的蛇,对$10^9+7$取模. 样例 ...
- [CSP-S模拟测试]:最小值(DP+乱搞)
题目背景 $Maxtir$更喜欢序列的最小值. 题目传送门(内部题128) 输入格式 第一行输入一个正整数$n$和四个整数$A,B,C,D$. 第二行输入$n$个整数,第$i$个数表示$a_i$. 输 ...
随机推荐
- JS基础_打印出1-100之间所有的质数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- centos 配置mysql主从复制
mysql+centos7+主从复制 MYSQL(mariadb) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:甲骨文公 ...
- logback替换log4j
1.新建logback.xml放在src目录下(放在src下会自动加载,不需要再web.xml配置) 2.引入必要的jar包:
- Redis之过期策略
一.设置过期时间 Redis对存储值的过期处理实际上是针对该值的键(key)处理的,即时间的设置也是设置key的有效时间.Expires字典保存了所有键的过期时间,Expires也被称为过期字段. e ...
- 用帝国cms 反馈内容的时候自动发送邮箱开发流程
开发流程是这样的. 第一步:先找好一个发送的邮箱.以及一个接受的邮箱.这里是 测试的,我都用的qq邮箱,帝国cms后台配置如下: 注意:这里的SMTP服务器是腾讯的,如果你用163的或者其他的请自行百 ...
- element-ui select
1. 组合 label <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...
- DNS缓存失败怎么解决?
DNS的中文名是域名系统,是域名和IP地址相互映射的一个分布式数据库.有了DNS,我们上网时直接输入网站域名(即网址)即可,而不用输入网站的IP地址访问网站,对于用户来说比较方便记忆和访问. 每次当我 ...
- CentOS7安装node环境
1 找到官网复制链接地址 2 再自己Linux的按照路径,wget下载软件包并解压 wget https://nodejs.org/dist/v10.16.1/node-v10.16.1-linux- ...
- 《设计模式之美》 <01>为什么需要学习掌握设计模式?
1. 应对面试中的设计模式相关问 题学习设计模式和算法一样,最功利.最直接的目的,可能就是应对面试了.不管你是前端工程师.后端工程师,还是全栈工程师,在求职面试中,设计模式问题是被问得频率比较高的一类 ...
- [Suricata]无法禁用某些规则的解决办法
背景: 生产环境中部署了suricata,日常规则更新使用suricata-update,如果想禁用某些规则,可以在配置文件/etc/suricata/disable.conf中添加,比如: #禁用规 ...