题意:

定义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. 别再说“我已经努力了”,你的“努力”一文不值!

    有次,让一个研究生男收集一份资料,快下班了问结果,竟然毛也没有.见我要怒,他慷慨激昂地说:"我已经很努力找了,但真的查不到." 作为主管,"我已经努力"这话我不 ...

  2. Traffic Manager:Azure中国版 正式发布

     我们很高兴地宣布Azure Traffic Manager 现已面向中国版Azure正式发布.此版本现已投入生产,由企业 SLA支持,随时可用于生产场景中. 借助Azure Traffic Ma ...

  3. java 去掉字符串右侧空格

    public static String rightTrim(String str) {    String regex = "(.*\\S+)(\\s+$)";    Patte ...

  4. Poj 3580-SuperMemo Splay

    题目:http://poj.org/problem?id=3580   SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submis ...

  5. hdoj 2141 Can you find it?【二分查找+暴力】

    Can you find it? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/Others ...

  6. hdoj 1342 Lotto【dfs】

    Lotto Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  7. c#基础语言编程-正则表达式应用

    引言 在不同语言中虽正则表达式一样,但应用函数还是有所区别,在c#语言中使用Regex. 可以通过以下两种方式之一使用正则表达式引擎: 通过调用 Regex 类的静态方法. 方法参数包含输入字符串和正 ...

  8. JSON 数据的系统解析

    - (IBAction)jsonSystemButtonDidClicked:(UIButton *)sender { self.JSONArray = [NSMutableArray array]; ...

  9. 往另外1个ListView中添加当前选中的项目

      //往另外1个ListView中添加当前选中的项目   function AddSelItems(listview1:TListView;ListView2:TListView):Boolean; ...

  10. OpenCV与QT联合编译 分类: Eye_Detection ZedBoard OpenCV shell ubuntu 2014-11-08 18:54 143人阅读 评论(0) 收藏

    问题1:首先参考rainysky的博客,发现qmake时发生找不到目录,文件的错误,又找不到 qmake.conf 文件的写法.所以开始按照网上的程序修改 XXX.pro 文件. 问题2:使用QT C ...