X链条

  题目大意,从1到N,1 = X0X1X2, …, 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)的更多相关文章

  1. poj 3421 X-factor Chains——质因数分解

    题目:http://poj.org/problem?id=3421 记忆化搜索竟然水过去了.仔细一想时间可能有点不对,但还是水过去了. #include<iostream> #includ ...

  2. POJ 3421 X-factor Chains

    线型素数筛+质因素分解+组合数. AC后发现这样做效率有点低..766ms. #include<stdio.h> #include<string.h> #include< ...

  3. POJ 3421 X-factor Chains (因式分解+排列组合)

    题意:一条整数链,要求相邻两数前一个整除后一个.给出链尾的数,求链的最大长度以及满足最大长度的不同链的数量. 类型:因式分解+排列组合 算法:因式分解的素因子个数即为链长,链中后一个数等于前一个数乘以 ...

  4. POJ 3421 X-factor Chains | 数论

    题意: 给一个x,求最长的排列满足开头是1,结尾是x,前一个数是后一个数的因子 输出长度和这样序列的个数 题解: 把x分解质因数,质因数个数就是答案,接下来考虑怎么求个数 显然这是一个可重集合全排列问 ...

  5. POJ 3421 X-factor Chains(构造)

    这条链依次乘一个因子.因为n<2^20,sqrt(n)分解因子,相同的因子相对顺序取一个. 组合公式计算一下就好. #include<cstdio> #include<iost ...

  6. POJ 3421分解质因数

    X-factor Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7375   Accepted: 2340 D ...

  7. POJ 3421

    X-factor Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5111   Accepted: 1622 D ...

  8. Mathematics:Find a multiple(POJ 2356)

    找组合 题目大意:给你N个自然数,请你求出若干个数的组合的和为N的整数倍的数 经典鸽巢原理题目,鸽巢原理的意思是,有N个物品,放在N-1个集合中,则一定存在一个集合有2个元素或以上. 这一题是说有找出 ...

  9. Mathematics:Raising Modulo Numbers(POJ 1995)

    阶乘总和 题目大意:要你算一堆阶乘对m的模... 大水题,对指数二分就可以了... #include <iostream> #include <functional> #inc ...

随机推荐

  1. 别老扯什么Hadoop了,你的数据根本不够大

    本文原名“Don't use Hadoop when your data isn't that big ”,出自有着多年从业经验的数据科学家Chris Stucchio,纽约大学柯朗研究所博士后,搞过 ...

  2. HTML5+学习笔记2-------边看代码边研究貌似还是有点问题...还在研究中api中

    // 拍照 function getImage() { outSet( "开始拍照:" ); var cmr = plus.camera.getCamera(); cmr.capt ...

  3. C#创建windows服务列表

    转载自:http://www.cnblogs.com/sorex/archive/2012/05/16/2502001.html Windows Service这一块并不复杂,但是注意事项太多了,网上 ...

  4. 微信电脑版真的要来了 微信Windows版客户端1.0 Alpha推出

    微信电脑版的搜索量一直很大,但只有网页版,之前也写了微信网页版APP - 网页微信客户端电脑版体验,在键盘上打字的感觉就是快.现在微信Windows版客户端1.0 Alpha推出了,来一睹芳容吧(20 ...

  5. Linux/CentOS 同步网络时间

    由于硬件的原因,机器或多或少的跟标准时间对不上,一个月的误差几秒到几分钟不等.对于服务器来说时间不准,会有很多麻烦.例如,支付的时候,无法下单,游戏无法登录等. 方法一:用 ntpdate从时间服务器 ...

  6. expdp / impdp 用法详解

    一  关于expdp和impdp     使用EXPDP和IMPDP时应该注意的事项:EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程 ...

  7. scoll滚动

    [前端性能]高性能滚动 scroll 及页面渲染优化   最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优 ...

  8. CCP浅谈

    说明 如果想详细了解CCP,可以下载AN-AMC-1-102_Introduction_to_CCP.pdf或者ccp211.pdf 本文不涉及到专业的知识讲解,如果想查看更加专业的知识可以选择看完以 ...

  9. SQL语句在查询分析器中可以执行,代码中不能执行

    问题:SQL语句在查询分析器中可以执行,代码中不能执行 解答:sql中包含数据库的关键字,将关键字用[]括起来,可以解决. 后记:建数据库的时候尽量避免使用关键字. 例子: sql.Format(&q ...

  10. CCF 模拟A 无脑大循环

    http://115.28.138.223:81/view.page?opid=1 第一题用一组STL函数查找即可 #include<iostream> #include<cstdi ...