poj3421(数论,素数,分解质因数,排列组合)

题目大意:

  给你一个定义:对于一个数n有一个数列 x0,x1,x2,x3,x4...xn,其中x0=1,xn=m,满足xi>xi-1且xi可以被xi-1整除

  问:这个数列最大长度是多少(最大的m值),链有多少种形式

  m的取值:数列的最大长度就是质因数的个数,因为后一个数可以整除前一个数,一直到最后一个数,每次整除都是一个因数,所以最长链必是因数个数

  链的形式:m个因数全排列后去重。因为链的形式是由每次乘的因数决定的(注意是全排列后去重,不是去重后再全排列)

  补一个数学知识:一个数列的全排列的个数是数列的数的个数的阶乘除以每个数出现的次数

  代码:

  

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<map>
 6 #define ll long long
 7 using namespace std;
 8 const int maxn=1e7+5;
 9 map<int,int>nums;
10 int n;
11 int cnt=0;
12 int cf=1;
13 inline ll jc(int a)
14 {
15     ll ans=1;
16     for(int i=1;i<=a;i++) ans*=i;
17     return ans;
18 }
19 //inline void solve()
20 
21 int main()
22 {
23     //freopen("in.in","r",stdin);
24     while(scanf("%d",&n)!=EOF)
25     {
26         nums.clear();
27         cnt=0;cf=1;
28         for(int i=2;i*i<=n;i++)
29         {
30             while(n%i==0)
31             {
32                 n/=i;
33                 nums[i]++;
34                 cnt++;
35             }
36             //if(nums[i]) cf*=nums[i];
37         }
38         if(n!=1){nums[n]++,cnt++;}
39         ll ans=jc(cnt);
40         //ans/=cf;
41         for(map<int, int>::iterator mi=nums.begin(); mi!=nums.end(); mi++)
42         {
43             ans /= jc(mi->second);
44         }
45         printf("%d %lld\n",cnt,ans);
46     }
47     return 0;
48 }
View Code

  ps:对于这种要用迭代器才能过,否则会超时的操作不是很懂,欢迎dalao来评论指导,(注释掉的方式竟然T了,注:注释掉的方式nums不是map是数组)

posted @ 2018-12-13 19:29  codeoos  阅读(448)  评论(0编辑  收藏  举报