WHU 1568 Product (DP、逆元)
题意:
定义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、逆元)的更多相关文章
- HDU 6656 Kejin Player (期望DP 逆元)
2019 杭电多校 7 1011 题目链接:HDU 6656 比赛链接:2019 Multi-University Training Contest 7 Problem Description Cub ...
- 5.10 省选模拟赛 tree 树形dp 逆元
LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...
- Eigen矩阵基本运算
1 矩阵基本运算简介 Eigen重载了+,-,*运算符.同时提供了一些方法如dot(),cross()等.对于矩阵类的运算符重载只支持线性运算,比如matrix1*matrix2是矩阵相乘,当然必须要 ...
- 1.2 eigen中矩阵和向量的运算
1.2 矩阵和向量的运算 1.介绍 eigen给矩阵和向量的算术运算提供重载的c++算术运算符例如+,-,*或这一些点乘dot(),叉乘cross()等等.对于矩阵类(矩阵和向量,之后统称为矩阵 类) ...
- Eigen教程(3)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 矩阵和向量的运算 提供一些概述和细节:关于矩阵.向量以及标量的运算. 介绍 Eige ...
- eigen 笔记1
c++ 的 eigen 类似于 python 的 numpy, 还有一个类似的库是 Armadillo, 当然还有 opencv. Armadillo 与 matlab 在函数名称上更接近, 但是 T ...
- UNION DISTINCT
w同结构表读写合并. DROP PROCEDURE IF EXISTS w_ww_amzasin; DELIMITER /w/ CREATE PROCEDURE w_ww_amzasin() BEGI ...
- Codeforces 543D Road Improvement(树形DP + 乘法逆元)
题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...
- Codeforces 543D. Road Improvement (树dp + 乘法逆元)
题目链接:http://codeforces.com/contest/543/problem/D 给你一棵树,初始所有的边都是坏的,要你修复若干边.指定一个root,所有的点到root最多只有一个坏边 ...
随机推荐
- dede织梦跨频道调用指定栏目文章的解决方法
很久没有写技术类的文章了,这次这个标题写的- 呃, 有一点儿纠结. 事情是这样的,刚刚回答了一个百度问答上的问题,这个问题的大体意思是,有一个图片栏目,内含3个子栏目,分别为图片栏目1.2和3,另有三 ...
- canvas——画板
注意部分: canvas的height和width不能再css中设定,应该在html中设定,否则会影响页面的分辨率. 效果图: 图1: 代码 css: #canvas{ cursor: crossha ...
- NHibernate 存储过程使用
NHibernate也是能够操作存储过程的,不过第一次配置可能会碰到很多错误. 一.删除 首先,我们新建一个存储过程如下: CREATE PROC DeletePerson @Id int AS DE ...
- bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)
1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 733 Solved: 451[Submit][Status ...
- HDU 3507 Print Article(DP+斜率优化)
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) ...
- Java 交换两个变量的数值
一.参数传递方法 为解决标题问题,首先介绍参数传递方法.目前各类程序设计语言的参数传递方法主要有三种: 按值传递 按引用传递 按指针传递 其中按值传递表示方法(函数)接收的是调用者提供的变量的拷贝,不 ...
- macbook pro install ubuntu
https://help.ubuntu.com/community/MacBookPro Determine your hardware revision To determine which ver ...
- nginx做负载均衡器以及proxy缓存配置 - SegmentFault
nginx做负载均衡器以及proxy缓存配置 - SegmentFault nginx做负载均衡器以及proxy缓存配置
- SVN 资源库报错 E175002
遇到一个问题, svn: E175002: OPTIONS request failed on '/' Connection timed out: connect 试了网上好多办法,都没有,最后公司大 ...
- 408. Valid Word Abbreviation
感冒之后 睡了2天觉 现在痊愈了 重启刷题进程.. Google的题,E难度.. 比较的方法很多,应该是为后面的题铺垫的. 题不难,做对不容易,edge cases很多,修修改改好多次,写完发现是一坨 ...