• UVA1635 Irrelevant Elements —— 唯一分解定理 + 二项式定理


    题目链接:https://vjudge.net/problem/UVA-1635

    (紫书320)



    题解:

    1.根据二项式定理, 可得递推公式: C(n,k) = (n-k+1)/k * C(n, k-1)

    2.某一项与余数(%m)无关, 即表明该项的的系数是m的倍数, 由于 1<=n<=1e5, 直接运算的话肯定溢出。

    所以 :将数字进行分解质因数, 记录质因子以及其个数。由于题目只需判断某项的系数是否为m的倍数, 所以只需要考虑m所拥有的质因子。

    3.fac[i]记录m的质因数, num_m[i]记录m的质因数fac[i]的个数, num_c[i]记录二项式系数(动态)的质因数fac[i]的个数。

    4.对于所有的i, 如果num_c[i] >= num_m[i] 则表明此系数是m的倍数, 即此项与余数无关。



    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <stack>
    11 #include <sstream>
    12 #include <algorithm>
    13 using namespace std;
    14 #define pb push_back
    15 #define mp make_pair
    16 #define ms(a, b)  memset((a), (b), sizeof(a))
    17 #define eps 0.0000001
    18 typedef long long LL;
    19 const int INF = 2e9;
    20 const LL LNF = 9e18;
    21 const int mod = 1e9+7;
    22 const int maxn = 1e5+10;
    23 
    24 int n, m, cnt;
    25 int fac[maxn], num_m[maxn], num_c[maxn];
    26 int ans[maxn], sum;
    27 
    28 void init()
    29 {
    30     n = n - 1;    //题目从a[1]~a[n], 而二项式定理中, 从a[0]~a[n], 所以要与二项式定理中的n对应。
    31     ms(num_m, 0);
    32     ms(num_c, 0);
    33     cnt = 0;
    34 
    35     int tmp = m;
    36     for(int i = 2; i*i<=tmp; i++)
    37     {
    38         if(tmp%i==0)
    39         {
    40             fac[++cnt] = i;
    41             while(tmp%i==0) tmp /= i, num_m[cnt]++;
    42         }
    43     }
    44     if(tmp>1) fac[++cnt] = tmp, num_m[cnt]++;
    45 }
    46 
    47 int test(int x)
    48 {
    49     int a = n-x+1;
    50     int b = x;
    51 
    52     for(int i = 1; i<=cnt; i++)
    53     {
    54         while(a%fac[i]==0) num_c[i]++, a /= fac[i];
    55         while(b%fac[i]==0) num_c[i]--, b /= fac[i];
    56     }
    57 
    58     for(int i = 1; i<=cnt; i++)
    59         if(num_m[i]>num_c[i]) return 0;
    60     return 1;
    61 }
    62 
    63 void solve()
    64 {
    65     sum = 0;
    66     for(int i = 1; i<=n-1; i++) //二项式的第0项和第n项都为1, 不需要考虑
    67         if(test(i))
    68             ans[++sum] = i+1;   //二项式的第i项, 对应题目中的第i+1项
    69 
    70     printf("%d
    ", sum);
    71     for(int i = 1; i<=sum; i++)
    72         printf("%s%d", i==1?"":" ", ans[i]);
    73     putchar('
    ');
    74 }
    75 
    76 int main()
    77 {
    78     while(scanf("%d%d",&n, &m)!=EOF)
    79     {
    80         init();
    81         solve();
    82     }
    83 }
    View Code


  • 相关阅读:
    【C】——sigprocmask 阻塞进程信号
    【C】——setjmp练习
    【程序练习】——交换两数组元素,使之和差最小
    【C】——setvbuf(scanf内存溢出问题)
    【C】——APUE小程序之递归遍历目录
    Java的原始类型(Primitive Type)
    类加载 静态加载
    行政拘留不属于行政强制措施
    行政立法主体
    行政法中三大具体行政行为
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538687.html
Copyright © 2020-2023  润新知