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. acdream1233 Royal Federation (构造?)

    http://acdream.info/problem?pid=1233 Andrew Stankevich's Contest (3) ASC 3 Royal Federation Special ...

  2. SQL like 模糊查询

    SQL 模糊查询 在进行数据库查询时,有完整查询和模糊查询之分. 一般模糊查询语句如下: SELECT 字段 FROM 表 WHERE 某字段 Like 条件 其中关于条件,SQL提供了四种匹配模式: ...

  3. UGUI事件解析

    http://www.tuicool.com/articles/7fYjMr http://www.xuanyusong.com/archives/3325

  4. log4net的基本配置及用法

    [1].[代码] [C#]代码 跳至 [1] [2] ? 1 2 using System.Reflection;  //使用反射 static private ILog log = log4net. ...

  5. UI第六节——UINavigationController 详解

    1. UINavigationController 是一个容器类.里面盛放的是UIViewController. 容器的意思是,如果你不放入UIViewController,里面就是空的,什么也没有. ...

  6. jquery选择器(三)-过滤选择器

    一.基本过滤选择器 二.内容过滤选择器 1. 包含文本内容为“text”的元素 2. 含有某个选择器所匹配的父元素 3. 包含有子元素或者文本的父元素 4. 不含有子元素或者文本的父元素 三.可见性过 ...

  7. PHP函数preg_replace() 正则替换所有符合条件的字符串

    PHP preg_replace() 正则替换,与JavaScript 正则替换不同,PHP preg_replace() 默认就是替换所有符号匹配条件的元素. preg_replace (正则表达式 ...

  8. 【C语言入门教程】7.3 结构体指针的定义和引用

    C 语言中指针的操作非常灵活,它也能指向结构体变量对结构体变量进行操作.在学习结构指针之前,需要再次加深对指针的认识.声明指针变量时所使用的数据类型修饰符实际上的作用是定义指针访问内存的范围,如果指针 ...

  9. sql存储过程几个简单例子

    导读:sql存储是数据库操作过程中比较重要的一个环节,对于一些初学者来说也是比较抽象难理解的,本文我将通过几个实例来解析数据库中的sql存储过程,这样就将抽象的事物形象化,比较容易理解. 例1: cr ...

  10. iOS开发——高级篇——UIDynamic 物理引擎

    一.UIDynamic 1.简介什么是UIDynamicUIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象重力.弹性碰撞 ...