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最多只有一个坏边 ...
随机推荐
- jQuery zxxbox弹出框插件(v3.0)
插件地址: http://www.zhangxinxu.com/study/201009/jquery-zxxbox-v3-demo.html
- 【转】实现展开列ExpandableListView的三种方式之SimpleExpandableListAdapter实例
原文网址:http://blog.csdn.net/x605940745/article/details/12099709 实现可扩展展开列ExpandableListView的三种方式 欢迎加入QQ ...
- Unity5 Screen-Space Subsurface Scattering屏幕空间次表面散射SSSSS
用unity5自带的standard shader ------------by wolf96
- unity3d 制造自己的水体water effect(二)
前篇:unity3d 制造自己的水体water effect(一) 曲面细分:Unity3d 使用DX11的曲面细分 PBR: 讲求基本算法 Unity3d 基于物理渲染Physically-Base ...
- 《University Calculus》-chaper8-无穷序列和无穷级数-泰勒定理的证明
泰勒定理: 证明:
- 钥匙计数之一 - HDU 1438(状态压缩打表)
分析:首先想到每个钥匙的结尾有4种状态,不过题目还需要判断有三种不同的钥匙深度,所以每种深度结尾后有2^4种状态,0000->1111,不过题目还需需要有相邻的钥匙深度大于等于3,所以需要两种不 ...
- HDU 4414 Finding crosses (DFS + BFS)
题意:在N*N的图中,找出孤立存在的十字架的个数.十字架要求为正十字,孤立表示组成十字架的‘#的周围的一格再无’#‘. dfs找出在中心的‘#’(周围四格也为‘#'),则缩小了搜索范围,再bfs找出是 ...
- PHP——四种基本排序算法
分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中的值按照从小到大的顺序进行排序. $arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序 思路分析 ...
- thinkphp 获取客户端ip地址方法
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有 ...
- bzoj2822: [AHOI2012]树屋阶梯
咦,这里有好多东西https://en.wikipedia.org/wiki/Catalan_number 每个矩形最多贡献一个拐角 枚举左上角的点和那个拐角是一个矩形 #include<cst ...