Mathematics:X-factor Chains(POJ 3421)

题目大意,从1到N,1 = X0, X1, X2, …, Xm = X中间可以分成很多数,另Xi < Xi+1 Xi 可以整除Xi+1 ,求最大长度m和m长度的链有多少条
思路:
很简单,只要把数分解质因数就可以了,最后链条的长度为质因数的个数,组合数为质因数个数的阶乘除以各自重复质因数的阶乘。还记得我发过的GCM和LCM反转的那道题吗,可以用pallord_rho算法分解质因数。
贴代码,第一个是最坑爹的,这一题会专门出数据坑Miller_Rabin算法,所以必须素数验证必须执行8次以上,不能用srand改变种子,否则你就是在和上帝玩骰子。
#include <iostream>
#include <algorithm>
#include <functional>
#include <time.h> using namespace std;
typedef long long LL_INT; bool Miller_Rabin(const LL_INT);
LL_INT witness(const LL_INT,const LL_INT,const LL_INT);
void Find_Factors(const LL_INT, int *const, const int);
LL_INT Pallord_Rho_Theorem(const LL_INT, const int);
LL_INT Multi_Function(LL_INT,const LL_INT);
LL_INT gcd(LL_INT, LL_INT); static LL_INT factors[], factors_num[];
static long long coe[];
static int factors_sum[]; void Inivilize(void)
{
coe[] = ;
for (int i = ; i <= ; i++)
coe[i] = coe[i - ] * i;
} int main(void)
{
LL_INT x;
long long chains_sum;
int prime_sum, len, i; Inivilize();
while (~scanf("%lld", &x))
{
prime_sum = ; len = ;
if (x <= )
printf("0 1\n");
else if (Miller_Rabin(x))//如果是素数,直接返回1 1
printf("1 1\n");
else
{
Find_Factors(x, &prime_sum, );//120是经验值
sort(factors, factors + prime_sum);
factors_num[] = factors[];
memset(factors_sum, , sizeof(factors_sum));
factors_sum[] = ;
for (i = ; i < prime_sum; i++)
{
if (factors[i - ] == factors[i])
factors_sum[len]++;
else
{
factors_num[++len] = factors[i];
factors_sum[len] = ;
}
}
chains_sum = coe[prime_sum];
for (int i = ; i <= len; i++)
chains_sum /= coe[factors_sum[i]];
printf("%d %lld\n", prime_sum, chains_sum);
}
}
return ;
} bool Miller_Rabin(const LL_INT n)
{
if (n == )
return true;//如果是2,就不用判断了
else
{
for (int i = ; i < ; i++)
{
if (!(witness((LL_INT)(rand() % (n - )) + , n - , n) == ))
return false;
}
return true;
}
} LL_INT witness(const LL_INT coe, const LL_INT level, const LL_INT n)
{
LL_INT y, x;
if (level == )
return ;
x = witness(coe, level >> , n); if (x == )
return ;
y = (x*x) % n;
if (y == && x != && x != n - )
return ;//费马小定理的运用
if (level % == )
y = (coe*y) % n; return y;
} void Find_Factors(const LL_INT n, int *const len, const int times)
{
if (n == )
return;
else if (Miller_Rabin(n))
factors[(*len)++] = n;
else
{
LL_INT p = n;
int c = times;
while (p >= n)
p = Pallord_Rho_Theorem(n, c--);
Find_Factors(p, len, times);
Find_Factors(n / p, len, times);
}
} LL_INT Pallord_Rho_Theorem(const LL_INT n, const int c)
{
LL_INT x, y, k = , d;
x = y = rand() % n;//随意取一个随机数 for (int i = ;; i++)
{
x = (Multi_Function(x, n) + c) % n;
d = gcd(n, (y - x + n) % n);//计算|y-x|与n的最大公因数
if ( < d && d < n)
return d;
else if (y == x)
return n;//相当于这个因数分解是失败的,所以直接返回n让外层循环继续
else if (i == k)//brent判据,目的就是找到在偶数周期内找到gcd(x(k)-x(i/2))
{
y = x;//重新y=x,定义循环
k <<= ;
}
}
return n;
} LL_INT Multi_Function(LL_INT x,const LL_INT mod)
{
LL_INT y = x, ans = ;
while (y)//计算y=x^2的取模算法
{
if (y & )
ans = (ans + x) % mod;
x = (x << ) % mod;
y >>= ;
}
return ans;
} LL_INT gcd(LL_INT a, LL_INT b)
{
if (b == )
return a;
return gcd(b, a%b);
}

挺慢的,其实直接用筛法更快,先把表打好,然后再一个一个选就可以了,用筛法的话可以到100ms以内
#include <iostream>
#include <functional>
#include <algorithm> using namespace std; static bool primes[( << ) + ];
static int primes_set[];
static long long fact[]; void Inivilize(int *const primes_sum)
{
int i, j;
primes[] = primes[] = ;
for (i = ; i <= << ; i++)
{
if (!primes[i]) primes_set[(*primes_sum)++] = i;
for (j = ; j*i <= << && j <= i; j++)
{
if (primes[j] == )
primes[j*i] = ;
}
}
fact[] = ;
for (i = ; i <= ; i++)
fact[i] = fact[i - ] * i;
} int main(void)
{
int x, last, i, tmp_div_sum, tmp_last, longest_length, primes_sum = , prime_num;
long long div_sum, chain_sum;
Inivilize(&primes_sum); while (~scanf("%d", &x))
{
if (x == )
printf("0 1\n");
else
{
div_sum = ; last = x; longest_length = ;
for (i = ; last != ; i++)
{
if (!primes[last])
{
longest_length++;
break;
}
prime_num = primes_set[i];
for (tmp_div_sum = , tmp_last = last; tmp_last%prime_num == ;)
{
if (!tmp_last) break;
tmp_last /= prime_num;
tmp_div_sum++; longest_length++;
}
last = tmp_last;
if (tmp_div_sum)
div_sum *= fact[tmp_div_sum];
}
chain_sum = fact[longest_length];
chain_sum /= div_sum;
printf("%d %lld\n", longest_length, chain_sum);
}
}
return ;
}

Mathematics:X-factor Chains(POJ 3421)的更多相关文章
- poj 3421 X-factor Chains——质因数分解
题目:http://poj.org/problem?id=3421 记忆化搜索竟然水过去了.仔细一想时间可能有点不对,但还是水过去了. #include<iostream> #includ ...
- POJ 3421 X-factor Chains
线型素数筛+质因素分解+组合数. AC后发现这样做效率有点低..766ms. #include<stdio.h> #include<string.h> #include< ...
- POJ 3421 X-factor Chains (因式分解+排列组合)
题意:一条整数链,要求相邻两数前一个整除后一个.给出链尾的数,求链的最大长度以及满足最大长度的不同链的数量. 类型:因式分解+排列组合 算法:因式分解的素因子个数即为链长,链中后一个数等于前一个数乘以 ...
- POJ 3421 X-factor Chains | 数论
题意: 给一个x,求最长的排列满足开头是1,结尾是x,前一个数是后一个数的因子 输出长度和这样序列的个数 题解: 把x分解质因数,质因数个数就是答案,接下来考虑怎么求个数 显然这是一个可重集合全排列问 ...
- POJ 3421 X-factor Chains(构造)
这条链依次乘一个因子.因为n<2^20,sqrt(n)分解因子,相同的因子相对顺序取一个. 组合公式计算一下就好. #include<cstdio> #include<iost ...
- POJ 3421分解质因数
X-factor Chains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7375 Accepted: 2340 D ...
- POJ 3421
X-factor Chains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5111 Accepted: 1622 D ...
- Mathematics:Find a multiple(POJ 2356)
找组合 题目大意:给你N个自然数,请你求出若干个数的组合的和为N的整数倍的数 经典鸽巢原理题目,鸽巢原理的意思是,有N个物品,放在N-1个集合中,则一定存在一个集合有2个元素或以上. 这一题是说有找出 ...
- Mathematics:Raising Modulo Numbers(POJ 1995)
阶乘总和 题目大意:要你算一堆阶乘对m的模... 大水题,对指数二分就可以了... #include <iostream> #include <functional> #inc ...
随机推荐
- php页面防重复提交方法总结
1.提交按钮置disabled 当用户提交后,立即把按钮置为不可用状态.这种用js来实现. 提交前 复制代码 代码如下: $("#submit").attr('di ...
- JAVA浅析字节流与字符流
[概括] 字节流是通用的,既可以操作图片又可以操作文本,但一般都用于操作图片.字符流是基于字节流的,因为字符流内部融合编码表,所以用来操作文本. 1.在字节输入流中能根据文件的大小来开辟数组空间 Fi ...
- Redhat系统网络配置
1.RedHat系统的网络配置文件/etc/sysconfig/network-scirpts/ifcfg-<interface-name>文件 DEVICE=eth0 ...
- NOIP2005 等价表达式
题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数 ...
- Python 集合set添加删除、交集、并集、集合操作符号
在Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 1. ...
- Hadoop之Storm安装
nimbus:主节点,负责分发代码,分配任务(只能有一个)supervisor:从节点,负责执行任务(可以有多个) jdkzookeeper(192.168.1.170/171/172)建议在zook ...
- Windows下MySQL 5.6安装及配置详细图解
一.安装前的准备 1.下载安装程序包,可到MySQL官方网站http://www.mysql.com/下载,如图1-1: 图1-1 下载后的安装文件如图1-2所示: 图1-2 二.安装 1.双击下载的 ...
- Hello 畅连·西瓜 帮助与更新
无感认证很好用,软件不再更新, 感谢每一位朋友的陪伴,谢谢! (2016.12.15) 百度云:点击下载 ------------旧版更新日志------------- Hello 畅连·西瓜 官网: ...
- AChartEngine方法的使用及事件汇总
前段时间接触了AChartEngine,在数据显示方面感觉非常好用,然后经过一段时间的接触,对于AChartEngine的扩展和使用有了一些整理和总结,本着技术共享的原则,分享给大家.我整理的东西都是 ...
- leetcode 63. Unique Paths II
Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...