原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf

题目翻译:

问题描述

  一个最基本的算数法则就是大于1的整数都能用1个或多个素数相乘的形式表示出来。当然,可以安排出多种的质因子排列方案,例如:10=2*5=5*2 20=5*2*2=2*5*2=2*2*5
  让我们用f(k)表示k的质因子排列方案数,如f(10)=2,f(20)=3。
  给你一个正整数n,至少有一个k使得f(k)=n,我们想知道最小的k是多少。

输入格式

  输入文件至多有1000组数据,每组数据单独成行上,包含一个正整数n(n<2^63)。

输出格式

  对于每组数据,输出他的问题n和最小的满足f(k)=n的k(k>1),数据保证k<2^63。

样例输入

1
2
3
105

样例输出

1 2
2 6
3 12
105 720

题目大意:假如一个大于2的正整数n的所有质因子的排列方式数为p(相同质因子调换位置不算),求满足条件的最小的n。

思路分析:

这一看又是一道数学题(而且是一道相当暴力的数学题……),首先我们将问题反过来,假如给出一个数n,求它的所有质因子排列方式数p。这个问题不难解决,我们先对n进行质因子分解,得到以下这个式子(其中\(p_i\)代表第i个质数)\[n=2^{a_1}\cdot 3^{a_2}\cdot 5^{a_3}\cdots p_{i}^{a_i},\]然后我们很轻易地通过组合公式得到如下这个答案\[p=\frac{\left(a_1+a_2+a_3+\cdots+a_i\right)!}{a_1!\cdot a_2!\cdot a_3!\cdots a_i!} \qquad (*) ,\]

这样我们就有了思路:将p转换成(*)式的形式,然后求出对应的序列\(\{a_i\}\),然后将第i个质数的指数赋为\(a_i\),然后反着求出n就好了。说起来容易但是算起来费劲……那么多数字的阶乘根本无法计算,我们要想办法缩小问题的规模,设\(\{a_i\}\)的位数为m,设\(w=\sum_{k=1}^m a_k\),考虑到题目中限定的n和p都小于\(2^{63}-1\),而根据我们的定义一定有\(n\le2^w\),而且由于\(a_i>0且a_i\ge a_{i+1}\),所以必然有\(m<63,\quad w<63\),这样我们就将问题的规模限定了,但是63!还是很难直接计算,所以我们需要对(*)式进行等价变换,将它限制在63以内的组合数的运算中,我们可以得到\[\frac{\left(a_1+a_2+a_3+\cdots+a_i\right)!}{a_1!\cdot a_2!\cdot a_3!\cdots a_i!}={w \choose a_1}\cdot{w-a_1 \choose a_2}\cdot{w-a_1-a_2 \choose a_3}\cdots{a_m \choose a_m}\qquad(**)\]

至此我们又看到了一丝希望,我们可以通过枚举所有计算出来的(**)式值在\(2^{63}\)以内的序列\(\{a_i\}\)然后计算它们对应的(**)式值和n,然后按照(**)式值进行排序,然后根据给出的询问在暴搜得到的序列中二分出来答案即可

(不知不觉这道题就讲完了)

算法流程:

1.打表前63个质数(这个手动打表就可以)

2.递推计算出所有63以内的组合数的值,备用

3.暴搜序列\(a_i\),同时计算出它们对应的p和n(一道算到某一步时p或n有爆long long的嫌疑立刻抛弃之,不符合数据范围)

4.以p为关键字排序

5.读入,二分出结果

复杂度分析:

这是一个暴搜,搜出来的序列数不会超过50000个,然后……就没有然后了(这个复杂度太难估算)

参考代码:

 //date 20130122
#include <cstdio>
#include <cstring>
#include <algorithm> typedef long long LL; const LL MAX = 0x7FFFFFFFFFFFFFFFLL; int c[][];
const int prime[] = {, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
LL x; int stat[][];
int a[];
int count;
int p = ; long long dp[][]; void work(int n, int m)
{
if(n < m){dp[n][m] = ; return;}
if(n == m || m == ){dp[n][m] = ; return;}
if(m == ){dp[n][m] = n; return;} if(dp[n - ][m] == -)work(n - , m);
if(dp[n - ][m - ] == -)work(n - , m - );
dp[n][m] = dp[n - ][m - ] + dp[n - ][m];
} struct pair
{
long long n, k;
}num[]; inline bool cmp(pair A, pair B)
{
if(A.n != B.n)return A.n < B.n;
else return A.k < B.k;
} void DFS(int k, int last, int sum)
{
if(sum > )return;
for(int i = ; (i <= last) && (sum + i <= ); ++i)
{
a[k] = i;
long long now = ;
int sign = ;
int cur = sum + a[k]; long long q = ;
for(int j = ; j <= k; ++j)
{
if(MAX / dp[cur][a[j]] < q){return;}
else{q *= dp[cur][a[j]]; cur -= a[j];}
for(int w = ; w <= a[j]; ++w)
{
if(MAX / prime[j] < now)return;
now *= prime[j];
}
}
for(int j = ; j <= k; ++j)
{
stat[count][j] = a[j];
}
++count;
num[count].n = q; num[count].k = now;
DFS(k + , i, sum + i);
}
} inline void hittable()
{
count = ;
memset(dp, 0xFF, sizeof dp);
dp[][] = ;
for(int i = ; i <= ; ++i)dp[i][] = ;
for(int i = ; i <= ; ++i)
work(, i);
DFS(, , );
} inline LL solve(LL x)
{
int l = , r = p, mid;
while(l < r)
{
mid = (l + r) >> ;
// printf("%d %d %d %lld %lld\n", l, r, mid, num[mid].n);
if(num[mid].n == x)return num[mid].k;
if(num[mid].n < x)l = mid + ;
else r = mid - ;
}
return num[l].k;
} int main()
{
freopen("factors.in", "r", stdin);
freopen("factors.out", "w", stdout); hittable();
std::sort(num + , num + count + , cmp);
long long w = num[].n;
for(int i = ; i <= count; ++i)
{
while(num[i].n == w){num[i].n = MAX; ++i;}
++p; w = num[i].n;
}
std::sort(num + , num + count + , cmp); while(scanf("%I64d", &x) != EOF)
{
LL w = solve(x);
printf("%I64d %I64d\n", x, w);
}
return ;
}

需要注意的问题:

1.打表要用机器打表,否则代码长度会太大……

2.判断是否会爆的时候不能直接比较(那样就已经乘爆了),应该把它转化成除法比较

ACM - ICPC World Finals 2013 D Factors的更多相关文章

  1. ACM - ICPC World Finals 2013 C Surely You Congest

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 试题来源 ACM/ICPC World Fin ...

  2. ACM - ICPC World Finals 2013 A Self-Assembly

    原题下载 : http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这道题其实是2013年我AC的第一道题,非常的开心,这 ...

  3. ACM - ICPC World Finals 2013 F Low Power

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 有n个机器,每个机器有2个芯片,每个 ...

  4. ACM - ICPC World Finals 2013 I Pirate Chest

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 海盗Dick受够了在公海上厮杀.抢劫 ...

  5. ACM - ICPC World Finals 2013 H Матрёшка

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 俄罗斯套娃是一些从外到里大小递减的传 ...

  6. ACM - ICPC World Finals 2013 B Hey, Better Bettor

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这题真心的麻烦……程序不长但是推导过程比较复杂,不太好想 ...

  7. [算法竞赛入门经典]Message Decoding,ACM/ICPC World Finals 1991,UVa213

    Description Some message encoding schemes require that an encoded message be sent in two parts. The ...

  8. UVa210 Concurrency Simulator (ACM/ICPC World Finals 1991) 双端队列

    Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but ...

  9. 谜题 (Puzzle,ACM/ICPC World Finals 1993,UVa227)

    题目描述:算法竞赛入门经典习题3-5 题目思路:模拟题 #include <stdio.h> #include <string.h> #define maxn 55 char ...

随机推荐

  1. 关于json的知识整理

    一.什么是json JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是存储和交换文本信息的语法.类似 XML,但JSON 比 XML 更 ...

  2. 1515 跳 - Wikioi

    题目描述 Description邪教喜欢在各种各样空间内跳.现在,邪教来到了一个二维平面.在这个平面内,如果邪教当前跳到了(x,y),那么他下一步可以选择跳到以下4个点:(x-1,y), (x+1,y ...

  3. java接口的方法默认都是public abstract类型

    java接口的方法默认都是public abstract类型, 因此我们在编写接口的实现类的时候,方法的实现前面要显式的加上public访问控制符

  4. Leetcode#79 Word Search

    原题地址 依次枚举起始点,DFS+回溯 代码: bool dfs(vector<vector<char> > &board, int r, int c, string ...

  5. iOS开发之数据存取3-CoreData自定义数据类型

    当系统提供的类型不能达到我们的使用要求时,比如我想在CoreData中存储UIColor,该怎么办呢? 这时候就要用到CoreData中非常强大的一个存储类型了:Transformable 下面将通过 ...

  6. MySQL主从关系设置(转)

    来源:LAMP兄弟连 作者:李恺 http://***/php/bencandy.php?fid=70&id=635 要做MySQL主从关系的设置,那么就得有两台MySQL主机.所以在开始之前 ...

  7. SQL语句备忘

    SELECT beatid,COUNT(d.id) dongnicount FROM `bed_beat_dongni` d INNER JOIN bed_beat b on b.id = d.bea ...

  8. auto_ptr的设计动机

    auto_ptr的设计动机 C++标准程序库提供的auto_ptr是一种智能型指针(smart pointer),帮助程序员防止“被异常抛出时发生资源泄露”. 函数的操作经常依以下模式进行: 1.获取 ...

  9. JsRender系列demo(3)-自定义容器

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. mysql 多表 update sql语句总结

    mysql 多表 update 有几种不同的写法. 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是ProductPrice表,我们要将ProductP ...