UVa 1635 (唯一分解定理) Irrelevant Elements

经过紫书的分析,已经将问题转化为求组合数C(n-1, 0)~C(n-1, n-1)中能够被m整除的个数,并输出编号(这n个数的编号从1开始)

首先将m分解质因数,然后记录下每个质因子对应的指数。

由组合恒等式,我们可以递推C(n, k)的质因数的个数。

 

一个没什么用的小优化:因为杨辉三角每一行都是对称的,所以我们可以求出前一半答案,然后根据对称性求出后一半的答案。

需要注意的是,如果答案中有类似C(10, 5)的数,就不要再对称了,会重复的。

这个优化貌似也只能优化0.05s左右。

 

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <cmath>

 4 

 5 const int maxn = 100000 + 10;

 6 int prime[maxn], bad[maxn], e[maxn], ans[maxn];

 7 int p_cnt;

 8 

 9 void prime_factors(int n)

10 {

11     p_cnt = 0;

12     int m = floor(sqrt(n) + 0.5);

13     for(int i = 2; i <= m; ++i)

14     {

15         if(n % i == 0)        { prime[p_cnt++] = i; }

16         while(n % i ==0)    { e[p_cnt-1]++; n /= i; }

17     }

18     if(n > 1)

19     {

20         prime[p_cnt] = n;

21         e[p_cnt++] = 1;

22     }

23 }

24 

25 int main()

26 {

27     int n, m;

28     while(scanf("%d%d", &n, &m) == 2)

29     {

30         memset(prime, 0, sizeof(prime));

31         memset(bad, 0, sizeof(bad));

32         memset(ans, 0, sizeof(ans));

33         memset(e, 0, sizeof(e));

34         n--;

35 

36         prime_factors(m);

37         for(int i = 0; i < p_cnt; ++i)

38         {

39             int p = prime[i];

40             int need = e[i];

41             int cur_e = 0;

42             for(int k = 1; k <= n/2; ++k)

43             {

44                 int x = n - k + 1;

45                 while(x % p == 0) { cur_e++; x /= p; }

46                 x = k;

47                 while(x % p == 0) { cur_e--; x /= p; }

48                 if(cur_e < need) bad[k] = 1;

49             }

50         }

51 

52         int ans_cnt = 0;

53         for(int k = 1; k <= n/2; ++k)

54             if(!bad[k]) ans[ans_cnt++] = k;

55         if(ans_cnt)

56         {

57             int p = ans_cnt-1;

58             if(ans[p] * 2 == n) p--;

59             for(int i = p; i >= 0; i--)

60                     ans[ans_cnt++] = n - ans[i];

61             printf("%d\n", ans_cnt);

62             printf("%d", ans[0] + 1);

63             for(int i = 1; i < ans_cnt; ++i) printf(" %d", ans[i] + 1);

64         }

65         else puts("0");

66         printf("\n");

67     }

68 

69     return 0;

70 }
代码君

 

你可能感兴趣的:(element)