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最多只有一个坏边 ...
随机推荐
- WebClient的超时问题及解决
WebClient的超时问题及解决 转自:http://blog.163.com/xiaozhi797@126/blog/static/62440288201112245345838/ Webcl ...
- python 正则表达式(一)
正则表达式(regular exprssion)是一种形式化语法描述的文本匹配模式.模式被解释为一组指令,然后会执行这组指令.以一个字符串作为输入,生成一个匹配的子集或源字符串的修改版本. 表达式可以 ...
- java基础 (六)面向对象(一)
这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...
- 文件夹oradiag_是如何产生的
如果sqlnet.ora不可用或者ADR_BASE参数未定义,那么11g的 SQL*Net将创建这些文件夹 (详情:http://download.oracle.com/docs/cd/B28359_ ...
- MRTG开源监控安装手册
环境要求: CentOS6以上版本 2G内存 16G存储 源码包下载:第一部分:下载,第二部分:下载 1.安装snmp: yum install -y net-snmp net-snmp-devel ...
- poj 2367 Genealogical tree【拓扑排序输出可行解】
Genealogical tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3674 Accepted: 2445 ...
- 【Lucene3.6.2入门系列】第15节_SolrJ高亮
package com.jadyer.solrj; import java.util.ArrayList; import java.util.List; import java.util.Map; i ...
- LogMiner详细讲解
原文地址:LogMiner 一.LogMiner的用途 日志文件中存放着所有进行数据库恢复的数据,记录了针对数据库结构的每一个变化,也就是对数据库操作的所有DML语句. 在Oracle 8i之前,Or ...
- OC封装的TLV数据格式解析库
作者:朱克锋 邮箱:zhukefeng@iboxpay.com 转载请注明出处:http://blog.csdn.net/linux_zkf TLV是一种可变格式,意思就是: Type类型, Leng ...
- winform Label与DataGridView右对齐 分类: WinForm 2014-05-19 20:51 446人阅读 评论(0) 收藏
实现Label与DataGridView对齐有两种方法,差别不大: 定义: Label名称:lblName DataGridView名称:dgvData 第一种: lblName.Location = ...