题意

询问有多少个数位为 \(n\) 的形如 \(11223333444589\) 的数位值不下降的数字在\(\mod p\) 的意义下同余 \(0\)。

$n\leq 10^{18}\ ,p\leq 500 $ 。

分析

  • 考虑普通的状态,矩乘和考虑每种数字选择什么都没法做,要另辟蹊径。

  • 发现这样的数字都可以拆分成1~9个形如 \(111111\) 的形式,记为 \(\rm gg\)。

  • 考虑算出所有此类数字在\(\mod p\) 意义下余数为 \(x\) 的有多少个。

  • 状态呼之欲出: \(f_{i,j,k}\) 表示考虑到 \(\rm gg\) 余数为 \(i\) 的 ,总的余数为 \(j\) ,已经选择了 \(k\) 个 \(\rm gg\) 的方案总数。

  • 转移枚举 \(\rm gg\) 余数为 \(i\) 的选择了多少个,注意这类 \(\rm gg\) 的选择是组合而不是排列,考虑插板法算方案。

  • 总时间复杂度为\(O(10^2*p^2)\)。

可重集的排列变组合可以考虑插板法。

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=504,mod=999911659;
LL st,n,p,rev[N],cnt[N],f[N][N][10],inv[N];
int pos[N];
void add(LL &a,LL b){a+=b;if(a>=mod) a-=mod;}
LL C(LL n,LL m){
LL res=1ll;
for(LL i=n-m+1;i<=n;++i) res=i%mod*res%mod;
for(LL i=2;i<=m;++i) res=res*inv[i]%mod;
return res;
}
int main(){
scanf("%lld%lld",&n,&p);
inv[1]=1;
for(int i=2;i<=500;++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
memset(pos,-1,sizeof pos);
pos[0]=0,rev[0]=0,cnt[0]=1;LL v=1%p;
for(LL i=1;i<=min(n,p);++i){
if(pos[v]!=-1){
LL len=i-pos[v],a=(n-i+1)/len,b=(n-i+1)%len;
st=rev[pos[v]+(b-1+len)%len];
for(int j=pos[v];j<i;++j) cnt[rev[j]]+=a+(j-pos[v]+1<=b);
break;
}else if(i==n) st=v;
pos[v]=i,rev[i]=v,cnt[v]++;
v=(v*10+1)%p;
}
rep(k,0,8) f[0][st][k]=C(cnt[0]+k-1,k); rep(i,1,p-1)
rep(j,0,p-1)
rep(k,0,8){
f[i][j][k]=f[i-1][j][k];
rep(h,1,k)
add(f[i][j][k],f[i-1][((j-h*i)%p+p)%p][k-h]*C(cnt[i]+h-1,h)%mod);
}
printf("%lld\n",f[p-1][0][8]);
return 0;
}

[BZOJ1974][SDOI2010]代码拍卖会[插板法]的更多相关文章

  1. SDOI2010代码拍卖会 (计数类DP)

    P2481 SDOI2010代码拍卖会 $ solution: $ 这道题调了好久好久,久到都要放弃了.洛谷的第五个点是真的强,简简单单一个1,调了快4个小时! 这道题第一眼怎么都是数位DP,奈何数据 ...

  2. Luogu2481 SDOI2010 代码拍卖会 DP、组合

    传送门 神仙DP 注意到\(N \leq 10^{18}\),不能够直接数位DP,于是考虑形成的\(N\)位数的性质. 因为低位一定不会比高位小,所以所有满足条件的\(N\)位数一定是不超过\(9\) ...

  3. 洛谷 P2481 [SDOI2010]代码拍卖会(背包+隔板法)

    题面传送门 题意: 给出 \(n,p\),求有多少 \(n\) 位数 \(X=a_1a_2a_3\dots a_n\) 满足: 该 \(n\) 位数不含前导零 \(a_i \leq a_{i+1}\) ...

  4. [SDOI2010]代码拍卖会

    题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...

  5. bzoj 1974: [Sdoi2010]代码拍卖会

    Description 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代 码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPi g不想把代码库给所有想要的小猪,只想 ...

  6. 洛谷 P2481 [SDOI2010]代码拍卖会

    洛谷 这大概是我真正意义上的第一道黑题吧! 自己想出了一个大概,状态转移方程打错了一点点,最后还是得看题解. 一句话题意:求出有多少个\(n\)位的数,满足各个位置上的数字从左到右不下降,且被\(p\ ...

  7. [SDOI2010]代码拍卖会——DP

    原题戳这里 绝对是一道好题 需要注意到两个东西 1.符合条件的数可以拆成一堆\(11...11\)相加的形式,比如\(1145=1111+11+11+11+1\) 2.\(1,11,111,1111, ...

  8. luogu P2481 [SDOI2010]代码拍卖会

    luogu 题目中的那个大数一定是若干个1+若干个2+若干个3...+若干个9组成的,显然可以转化成9个\(\underbrace {111...1}_{a_i个1}(0\le a_1\le a_2\ ...

  9. 【BZOJ-1974】auction代码拍卖会 DP + 排列组合

    1974: [Sdoi2010]auction 代码拍卖会 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 305  Solved: 122[Submit ...

随机推荐

  1. 使用Instruments中的CoreAnimation分析动画

    使用Instruments中的CoreAnimation分析动画 1. 打开Instruments中的CoreAnimation 2. 运行前的准备工作 要注意勾选以下选项,便于调试 3. 运行与调试 ...

  2. 可以简易设置文字内边距的EdgeInsetsLabel

    可以简易设置文字内边距的EdgeInsetsLabel 最终效果: 源码: EdgeInsetsLabel.h 与 EdgeInsetsLabel.m // // EdgeInsetsLabel.h ...

  3. MATLAB 正则表达式(一)(转)

    http://blog.sina.com.cn/s/blog_53f29119010009uf.html 正则表达式这个词上大学的时候就听同寝室的一个家伙常念叨——那家伙当然很厉害啦,现在已经发洋财去 ...

  4. Linux--面试题-01

    1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 来标识. 4. ...

  5. OpenCV2马拉松第2圈——读写图片

    收入囊中 用imread读取图片 用nameWindow和imshow展示图片 cvtColor彩色图像灰度化 imwrite写图像 Luv色彩空间转换 初识API 图像读取接口 image = im ...

  6. [SHOI2008]小约翰的游戏

    题目 不会,抄论文 这是一个非常牛逼的东西,叫做\(anti\)博弈,就是进行最后一次操作的人输 我们考虑一下这道题 显然如果石子个数都是\(1\),那么有奇数堆石子先手必败,有偶数堆石子先手必胜 如 ...

  7. php 添加 redis 扩展

    Windows下PHP安装Redis扩展的具体步骤方法 下面我们就结合详细的图文,给大家介绍Windows下PHP安装Redis扩展的方法: 首先我们打开这个上面给出的下载链接地址,界面如下: 这里我 ...

  8. no.random.randn

    numpy中有一些常用的用来产生随机数的函数,randn就是其中一个,randn函数位于numpy.random中,函数原型如下: numpy.random.randn(d0, d1, ..., dn ...

  9. js中css样式兼容各个浏览器写法

    在实际业务中往往需要在js中对dom添加一些样式,还需要对各个浏览器厂商的兼顾,看到一位大神写的一个方法很赞,做一个笔记 function prefixStyle(style){ var eleSty ...

  10. 封装一个统一返回json结果类JsonResult

    import java.io.Serializable; public class JsonResult implements Serializable{ private static final l ...