题意:

定义f(x) 为数x的所有数字的乘积.

求满足f(k)=f(x)的不同的不含数字1的k的个数.

x的长度小于50.

不超过1000组数据.


Solution:

由于函数是乘积的形式,可以由质因子着手分析:

数字的范围是1~9,1~9中只有2,3,5,7 四个质数,即f(x)可以表示为这四个质数的幂的乘积的形式.

注意到x的长度小于50,那么质因子最多不超过150(50个8),这个时候似乎可以通过枚举4 6 8 9这四个因子的个数来,得到答案.因为5,7可以单独处理,2和3的个数可以通过4,6,8,9的个数求得.另外4的个数不超过75.而6,8,9的个数也不超过50.从时间复杂度上看是我们能够接受的.但是数据有1000组.这似乎迫使我们采用能够预处理一些我们需要的东西的算法.

令f[k][i][j],为长度为k,含有i个2因子,j个3因子的数的个数.

对于f[k+1],不过是在k的后面加了2~9这8个数,只要对每个数,更新对应的i,j就行了.

这样我们可以先预处理足够大多的f[k][i][j],因为最多不过150个2因子,100个3因子,所以预处理到f[150][150][100]就够了.

对于一组输入,统计2,3,5,7这四个因子的个数,利用多重排列的公式计算出答案,因为要对除法取模,所以要用到逆元.

#include <iostream>
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const int MOD = ;
int n, m;
LL dp[][][], f[];
int sum[];
char s[];
LL Quikpower (LL Base, LL Power) {
LL k = ;
while ( Power > ) {
if (Power & ) k = (k * Base) % MOD;
Base = (Base * Base) % MOD;
Power >>= ;
}
return k;
}
LL cnt (LL k, int m, int a, int b) {
LL ans = k;
for (int i = ; i <= a + b; i++)
ans = ans * (m + i) % MOD;
ans = ans * Quikpower (f[a], MOD - ) % MOD;
ans = ans * Quikpower (f[b], MOD - ) % MOD;
return ans;
}
int main() {
f[] = ;
for (int i = ; i <= ; i++)
f[i] = (f[i - ] * i) % MOD;
dp[][][] = ;
for (int i = ; i <= ; i++)
for (int s2 = ; s2 <= ; s2++)
for (int s3 = ; s3 <= ; s3++) {
if (dp[i][s2][s3] == ) continue;
dp[i + ][s2 + ][s3] = (dp[i + ][s2 + ][s3] + dp[i][s2][s3]) % MOD;//
dp[i + ][s2][s3 + ] = (dp[i + ][s2][s3 + ] + dp[i][s2][s3]) % MOD; //
dp[i + ][s2 + ][s3] = (dp[i + ][s2 + ][s3] + dp[i][s2][s3]) % MOD;//
dp[i + ][s2 + ][s3 + ] = (dp[i + ][s2 + ][s3 + ] + dp[i][s2][s3]) % MOD; //
dp[i + ][s2 + ][s3] = (dp[i + ][s2 + ][s3] + dp[i][s2][s3]) % MOD;//
dp[i + ][s2][s3 + ] = (dp[i + ][s2][s3 + ] + dp[i][s2][s3]) % MOD; //
}
while (scanf ("%d", &n) != EOF) {
scanf ("%s", s);
memset (sum, , sizeof sum);
for (int i = ; i < n; i++) {
int k = s[i] - '';
if (k == || k == || k == ) sum[]++;
if (k == || k == ) sum[] += ;
if (k == || k == ) sum[]++;
if (k == ) sum[] += ;
if (k == ) sum[]++;
if (k == ) sum[]++;
}
int m = sum[] + sum[];
LL ans = ;
if (m + sum[] + sum[] != )
for (int i = ; i <= m; i++)
if (dp[i][sum[]][sum[]])
ans = (ans + cnt (dp[i][sum[]][sum[]], i, sum[], sum[]) ) % MOD;
cout << ans << endl;
}
}

WHU 1568 Product (DP、逆元)的更多相关文章

  1. HDU 6656 Kejin Player (期望DP 逆元)

    2019 杭电多校 7 1011 题目链接:HDU 6656 比赛链接:2019 Multi-University Training Contest 7 Problem Description Cub ...

  2. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  3. Eigen矩阵基本运算

    1 矩阵基本运算简介 Eigen重载了+,-,*运算符.同时提供了一些方法如dot(),cross()等.对于矩阵类的运算符重载只支持线性运算,比如matrix1*matrix2是矩阵相乘,当然必须要 ...

  4. 1.2 eigen中矩阵和向量的运算

    1.2 矩阵和向量的运算 1.介绍 eigen给矩阵和向量的算术运算提供重载的c++算术运算符例如+,-,*或这一些点乘dot(),叉乘cross()等等.对于矩阵类(矩阵和向量,之后统称为矩阵 类) ...

  5. Eigen教程(3)

    整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 矩阵和向量的运算 提供一些概述和细节:关于矩阵.向量以及标量的运算. 介绍 Eige ...

  6. eigen 笔记1

    c++ 的 eigen 类似于 python 的 numpy, 还有一个类似的库是 Armadillo, 当然还有 opencv. Armadillo 与 matlab 在函数名称上更接近, 但是 T ...

  7. UNION DISTINCT

    w同结构表读写合并. DROP PROCEDURE IF EXISTS w_ww_amzasin; DELIMITER /w/ CREATE PROCEDURE w_ww_amzasin() BEGI ...

  8. Codeforces 543D Road Improvement(树形DP + 乘法逆元)

    题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...

  9. Codeforces 543D. Road Improvement (树dp + 乘法逆元)

    题目链接:http://codeforces.com/contest/543/problem/D 给你一棵树,初始所有的边都是坏的,要你修复若干边.指定一个root,所有的点到root最多只有一个坏边 ...

随机推荐

  1. FBReader移植日记 第一天

    1.目标是创建两个工程,一个j2se的桌面软件,用于编辑和预览epub等格式的电子书,预览的窗口可以设置分辨率来模拟不同的设备,把编辑的结果实时的显示出来.另一个是Android的应用,用于阅读,管理 ...

  2. BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)

    1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1848  Solved: 936 [Submit][Sta ...

  3. iOS设备隐藏StateBar

    //隐藏StateBar - (BOOL)prefersStatusBarHidden {     returnYES; }

  4. 来更新一篇blog吧

    最近做了一下hackerrank的20/20的比赛.平时都只能过2题,这周顺利地通过了四道题目竟然.当妄图冲击衬衫的时候,发现剩下三个题一点招数都没有,之后就跑去看了一下node.js了... 这次比 ...

  5. win7重装系统时,使用PE工具箱进入系统看到的“C盘变成0.2G,D盘变成48G左右”这是什么回事?

    引入: 今天帮同学重装系统,重装系统使用的方法是利用PE工具箱制作出启动U盘,进行重装系统. 我的步骤是 第一步:开机按F2挂载U盘优先启动,于是开机时就进入PE微系统 第二步: 用分区工具(Disk ...

  6. VS2012 win7 修改TFS登陆账号的方法

    .修改登陆账号: 在网上搜了好多,都没有找到解决方法,自己琢磨了一会找到了修改登陆TFS(Team Foundation Server)(团队资源管理器)的账号,和大家分享一下吧. 点击“开始”--“ ...

  7. Win7无法设置背景图片的快速解决办法

    不知道怎么回事,win7电脑突然连个性化设置背景图片的按钮都没了.真操蛋~~~满屏的黑色背景图案,看着实在是不爽. 为了解决这个问题,网上搜索了好长时间,都不尽然! 最后想到了一个超简单的方法就是: ...

  8. MapReduce分析明星微博数据

    互联网时代的到来,使得名人的形象变得更加鲜活,也拉近了明星和粉丝之间的距离.歌星.影星.体育明星.作家等名人通过互联网能够轻易实现和粉丝的互动,赚钱也变得前所未有的简单.同时,互联网的飞速发展本身也造 ...

  9. 走进 Facebook POP 的世界

    POP: 一个流行的可扩展的动画引擎iOS,它支持spring和衰变动态动画,使其可用于构建现实,基于物理交互.Objective - C API允许快速集成, 对于所有的动画和过渡他是成熟的. 解释 ...

  10. javascript 高级程序设计(三)-数据类型

    ECMAScript 中所有类型的值都有与这两个Boolean值等价的值   数据类型     转换为true的值   转换为false的值 Boolean true   false( String ...