• 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
    ", 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("
    ");
    67     }
    68 
    69     return 0;
    70 }
    代码君
  • 相关阅读:
    应该做什么样的研究:以Google为例
    机器学习问题方法总结
    浅析PageRank算法
    轮廓处理函数详细
    近视恢复方法
    一步一步深入视频接口
    什么是cookie
    Linux系统目录数和文件数限制
    九大视频接口全接触
    实时监控网卡流量的命令
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4165648.html
Copyright © 2020-2023  润新知