• UVA1635 Irrelevant Elements(唯一分解定理 + 组合数递推)


    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51196

    紫书P320;

    题意:给定n个数a1,a2····an,依次求出相邻两个数值和,将得到一个新数列,重复上述操作,最后结果将变为一个数,问这个数除以m的余数与那些数无关?例如n=3,m=2时,第一次得到a1+a2,a2+a3,在求和得到a1+2*a2+a3,它除以2的余数和a2无关。1=<n<=10^5, 2=<m<=10^9

     其实就是杨辉三角的某一行有几个能整除m,求C(0,n - 1),C(1, n - 2)... C(n - 1, n - 1)中那几个能整除m

    解题思路:

    1、首先我们可以发现对于给定的n其实每项的系数就是C(n-1,i-1),所以我们只需要找到每项的系数对m取余是否为0即可

    2、由于m的取值范围为10^9,所以我们只需要筛选 √(10^9)的素数,然后对m进行分解;如果分解后m>1,说明当前m的是原m的一个素数,而且m> √(10^9),因此我们只需记录它即可

    3、由组合数的递推公式C(k, n) = (n - k + 1) / k * C(k - 1, n),而这道题n = n - 1;首项是一,可以直接从第二项即k = 1: (n - 1 )  - k + 1 / k开始判断是否能整除m,分子能整除素数元素个数就减一,分母能整除就+1,如果对于任意一个素数对应的指数 >= 1,就说明不能整除

    收获:

    每个整数的唯一分解式项数不多(long long 类型的数值最多20项,前21个素数相乘long long就溢出了)

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstring>
      5 using namespace std;
      6 const int Max = 40000;
      7 
      8 int factor[20],nfactor[20],num_factor,flag_factor[100000 + 10];
      9 int count_prime,prime[Max + 5],flag[Max + 5];
     10 void get_prime()
     11 {
     12     memset(flag, 0, sizeof(flag));
     13     count_prime = 0;
     14     for(int i = 2; i <= Max; i++)
     15     {
     16         if(flag[i] == 0)
     17         {
     18             flag[i] = 1;
     19             prime[++count_prime] = i;
     20             for(int j = 2; j <= Max / i; j++)
     21             {
     22                 flag[i * j] = 1;
     23             }
     24         }
     25     }
     26 }
     27 
     28 void get_factor(int m)
     29 {
     30     num_factor = 1;
     31     memset(nfactor, 0, sizeof(nfactor));
     32     memset(factor, 0, sizeof(factor));
     33     for(int i = 1; i <= count_prime; i++)
     34     {
     35         if(m < prime[i])
     36             break;
     37         if(m % prime[i] == 0)
     38         {
     39             factor[num_factor] = prime[i];
     40             while(m % prime[i] == 0 && m)
     41             {
     42                 nfactor[num_factor]++;
     43                 m = m / prime[i];
     44             }
     45             num_factor++;
     46             if(m == 0 || m == 1)
     47                 break;
     48         }
     49     }
     50     if(m > 1)
     51     {
     52         factor[num_factor] = m;
     53         nfactor[num_factor]++;
     54         num_factor++;
     55     }
     56 }
     57 bool check(int x, int y)
     58 {
     59     bool check_flag = true;
     60     for(int i = 1; i < num_factor; i++)
     61     {
     62         while(x % factor[i] == 0 && x)
     63         {
     64             x = x / factor[i];
     65             nfactor[i]--;
     66         }
     67         while(y % factor[i] == 0 && y)
     68         {
     69             y = y / factor[i];
     70             nfactor[i]++;
     71         }
     72         if(nfactor[i] >= 1)
     73         {
     74             check_flag = false;
     75             //break;  要不得,即使不能整除,也要约分完,因为下一个受这一个的影响
     76         }
     77     }
     78     return check_flag;
     79 }
     80 int main()
     81 {
     82     int n,m;
     83     get_prime();
     84     while(scanf("%d%d", &n, &m) != EOF)
     85     {
     86         get_factor(m);  //对m分解
     87         int cnt = 0, ends = 0;
     88         memset(flag_factor, 0, sizeof(flag_factor));
     89         for(int i = 1; i <= n; i++)
     90         {
     91             if( check(n - i, i) )   //原型就是 (n - 1 - i + 1) / i
     92             {
     93                 flag_factor[i + 1] = 1;
     94                 ends = i + 1;
     95                 cnt++;
     96             }
     97         }
     98         printf("%d
    ", cnt);
     99         if(cnt > 0)
    100         {
    101             for(int i = 1; i < ends; i++)
    102             if(flag_factor[i])
    103                 printf("%d ", i);
    104             printf("%d", ends);
    105         }
    106         printf("
    ");
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    Jmeter中ftp测试下载默认路径及文件
    python中http请求方法库汇总
    快速解决mysql Lost connection to MySQL server at 'reading initial communication packet及can't connect to mysql server on 'localhost'
    Python GUI--Tkinter实践
    Shell脚步之监控iostat数据
    C++二进制字符串转十六进制字符串 十六进制字符串转二进制字符串
    C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式
    DES加解密 cbc模式 的简单讲解 && C++用openssl库来实现的注意事项
    C++ 使用openssl库实现 DES 加密——CBC模式 && RSA加密——公加私解——私加公解
    C++ 解析json串
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5203582.html
Copyright © 2020-2023  润新知