<更新提示>

<第一次更新>


<正文>

数

Description

给定正整数n,m,问有多少个正整数满足:

(1) 不含前导0;

(2) 是m的倍数;

(3) 可以通过重排列各个数位得到n。

\(n\leq10^{20},m\leq100\)

Input Format

一行两个整数n,m。

Output Format

一行一个整数表示答案对998244353取模的结果。

Sample Input

1 1

Sample Output

1

解析

大致题意:给定一个位数不超过\(20\)位的正整数\(n\),求\(n\)的互异排列中有多少种情况恰为\(m\)的倍数,不能存在前导\(0\)。

假如\(n\leq10^{16},m\leq20\),那显然可以直接状压\(dp\)来计数,设\(f[S][i]\)代表\(n\)中取数情况为\(S\),得到的数模\(m\)余\(i\)的方案总数,可以枚举一个\(j\)来转移,时间复杂度\(O(2^{lg_n}lg_nm)\)。

当\(n\leq10^{20},m\leq100\)时,空间时间就都不行了。其实,在数字\(n\)中,很可能有多个一样的数字,而之前的状态我们把每一位数字都当做不一样的来处理,这样既费空间,又还需要额外判断重复状态。所以我们需要一种既能具体唯一表示状态,又不会有重复的状压方法。

对于这题来说,有一种很合适的状压方法:变进制状压。我们把\(0-9\)每一种数字各用了几次压成一个状态,例如\(0\)出现了一次,那么在状态中代表的权值就是\(1\),同理\(2\)个\(0\)代表的权值就是\(2\),假设有\(cnt_0\)个\(0\),那么权值就分别是\(1-cnt_0\),但是一个\(1\)代表的权值就是\(cnt_0+1\)了,一个\(1\)和一个\(0\)代表的权值是\(cnt_0+2\),两个\(1\)代表的权值是\(2cnt_0+1\),以此类推,这样可以以每一个数出现的次数来不重不漏地表示每一个状态。

显然,当每一个数字出现的次数尽可能平均时,代表的状态权值最大,实际测试可以发现最大权值不超过\(60000\),这样利用之前的转移方法就可以通过本题了,时间空间都没有问题。

\(Code:\)

#include <bits/stdc++.h>
using namespace std;
const int Mod = 998244353 , SIZE = 25 , Maxbit = 12 , M = 120 , MaxS = 60000;
char num[SIZE];
int m,len,cnt[Maxbit],f[MaxS][M];
int base[Maxbit],full[Maxbit],now[Maxbit];
inline void input(void)
{
scanf("%s",num+1);
len = strlen( num + 1 );
scanf("%d",&m);
}
inline void init(void)
{
for (int i=1;i<=len;i++)
cnt[ num[i] - '0' ] ++;
base[0] = 1 , full[0] = cnt[0];
for (int i=1;i<=9;i++)
{
base[i] = full[i-1] + 1;
full[i] = full[i-1] + base[i] * cnt[i];
}
}
inline void dp(void)
{
for (int i=1;i<=9;i++)
if ( cnt[i] )
f[base[i]][i%m] = 1;
for (int S=1;S<=full[9];S++)
{
int S_ = S;
for (int i=9;i>=0;i--)
if ( cnt[i] )
now[i] = cnt[i] - (S_/base[i]) , S_ %= base[i];
for (int i=0;i<=9;i++)
{
if ( !now[i] ) continue;
for (int j=0;j<m;j++)
{
int k = ( (j*10) % m + i ) % m;
f[ S + base[i] ][k] = ( f[ S + base[i] ][k] + f[S][j] ) % Mod;
}
}
}
}
int main(void)
{
input();
init();
dp();
printf("%d\n",f[full[9]][0]);
return 0;
}

<后记>

『数 变进制状压dp』的更多相关文章

  1. HDU 3001 Travelling 3进制状压dp

    题意:10个点,若干条边,边有花费,每个点最多走两次,求走过所有点,花费最少 分析:因为每个点最多走两次,所以联想到3进制,然后枚举状态,就行了(我也是照着网上大神的代码写的) #include &l ...

  2. T2963 贪吃蛇【BFS,四进制状压,A*】

    Online Judge:未知 Label:BFS,四进制状压,暴力,A*,哈希,玄学. 题目描述 给定一个n*m的地图和蛇的初始位置,地图中有些位置有石头,蛇不能经过.当然蛇也不能爬到地图之外. 每 ...

  3. ZRDay6A. 萌新拆塔(三进制状压dp)

    题意 Sol 这好像是我第一次接触三进制状压 首先,每次打完怪之后吃宝石不一定是最优的,因为有模仿怪的存在,可能你吃完宝石和他打就GG了.. 因此我们需要维护的状态有三个 0:没打 1:打了怪物 没吃 ...

  4. hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...

  5. HDU 3001 三进制状压DP

    N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方程: dp[i+b[k]][k]= ...

  6. 『Exclusive Access 2 dilworth定理 状压dp』

    Exclusive Access 2 Description 给出 N 个点M 条边的无向图,定向得到有向无环图,使得最长路最短. N ≤ 15, M ≤ 100 Input Format 第一行一个 ...

  7. UVA 10817 - Headmaster's Headache(三进制状压dp)

    题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=20&pag ...

  8. Travelling (三进制+状压dp)

    题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read(){ ,f= ...

  9. HDU - 3001 Travelling(三进制状压dp)

    Travelling After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best ch ...

随机推荐

  1. 不懂APS系统?十个问答让你对APS瞬间明明白白

    本文为您解答APS自动排程系统导入中客户常见的问题,帮助您评估企业是否适合导入APS,并了解需要的人力和资金的投入. Q1:哪些企业需要导入APS? A1: 编制生产计划有困难的企业都可以开始考虑导入 ...

  2. jmeter+jenkins配置过程

    目录 前置条件 脚本规划 讲解非GUI方式运行脚本 在jenkins里面新建项目 在Jmeter的jtl结果文件转换成html页面 邮件.配置 前置条件 1.jmeter安装好并已配置好环境变量,可正 ...

  3. idea 2019 集成activiti, idea activiti 新建bpmn文件, 解决idea activiti中文乱码

    idea 在线安装activiti插件 1. File-->Settings 2. 点击Plugins, 右侧界面点击Marketplace后在搜索框搜索 actiBPM 注: 网络原因没有加载 ...

  4. Python3+HTMLTestRunner生成html测试报告时报错HTMLTestRunner.py line 687, in generateReport  self.stream.write(output.encode('utf8'))

    1.测试环境及场景: Python3.5+unittest+HTMLTestRunner 生成html报告时候报错 2.报错内容: ..Traceback (most recent call last ...

  5. 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)

    [题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...

  6. Django常用自段和参数

    本文目录 1 ORM字段 2 ORM字段参数 3 关系字段 4 多对多关联关系的三种方式 5 元信息 6 自定义字段(了解) 回到目录 1 ORM字段 AutoField int自增列,必须填入参数 ...

  7. wordpress添加post_type自定义文章类型

    wordpress很强大,能当博客也能进行二次开发出很完善的内容管理系统满足企业运营需求,比如可以添加products产品模型.汽车模型等,如何实现呢?添加post_type自定义文章类型就可以了 p ...

  8. Ant Design的Form

    Ant Design的Form 使用onFieldsChange时不要与 mapPropsToFields一起使用,将导致表单校验等失效

  9. VMWare中CentOS 7 配置 XShell连接

    https://jingyan.baidu.com/article/363872ec796dfc6e4ba16f09.html http://www.cnblogs.com/iskylite/p/76 ...

  10. Pandas | 26 疏离数据

    当任何匹配特定值的数据(NaN/缺失值,尽管可以选择任何值)被省略时,稀疏对象被“压缩”. 一个特殊的SparseIndex对象跟踪数据被“稀疏”的地方. 这将在一个例子中更有意义. 所有的标准Pan ...