UVa 1635 Irrelevant Elements (唯一分解定理 || 组合数学)

题目

题目大意

对于给定的\(n\)个数\(a_1\), \(a_2\), ···, \(a_n\), 依次求出相邻两数之和, 将得到一个新数列。重复上述操作, 最后结果将变成一个数。问这个数除以\(m\)的余数将与哪些数无关? 例如\(n = 3\), \(m = 2\)时, 第一次求和得到\(a_1 + a_2\), \(a_2 + a_3\), 再求和得到\(a_1 + 2a_2 + a_3\), 它除以\(2\)的余数和\(a_2\)无关。\(1 ≤ n ≤ 10^5\), \(2 ≤ m ≤ 10^9\)。

题解

通过一些打表我们发现, 在一般情况下, 最后\(a_i\)的系数是\(C_{n - 1}^{i - 1}\)。例如\(n = 5\)时最后结果是\(a_1 + 4a_2 + 6a_3 + 4a_4 + a_5\)。这样问题就变成了\(C_{n - 1}^{0}\), \(C_{n - 1}^{1}\), ···, \(C_{n - 1}^{n - 1}\)中有哪些是\(m\)的倍数。

由此我们可以递推出所有\(C_{n - 1}^{i - 1}\), 但其中一部分太过巨大, 需要使用高精度。但此问题只关心那些是\(m\)的倍数, 于是又可以用到唯一分解定理。并且递推可以使用\(C_n^k = \frac{n - k + 1}{k}C_n^{k - 1}\), 不会涉及到高精度。

代码

#include<cstdio>
#include<cstring>
int n, m;
int factors[110][2], ccount[110], pascal[100010], num;
inline bool Judge(const int &n, const int &factor) {
  register int x(n - factor), y(factor);
  for (register int i(1), p; i <= num; ++i) {
    p = factors[i][0];
    while (!(x % p)) {
      x /= p;
      ++ccount[i];
    }
    while (!(y % p)) {
      y /= p;
      --ccount[i];
    }
  }
  for (register int i(1); i <= num; ++i) {
    if (ccount[i] < factors[i][1]) {
      return false;
    }
  }
  return true;
}
int main(int argc, char const *argv[]) {
  while (~scanf("%d %d", &n, &m)) {
    register int countt((num = 0));
    for (register int i(2); i * i <= m; ++i) {
      if (!(m % i)) {
        factors[++num][0] = i;
        factors[num][1] = 0;
        do {
          ++factors[num][1];
          m /= i;
        } while(!(m % i));
      }
    }
    if (m > 1) {
      factors[++num][0] = m;
      factors[num][1] = 1;
    }
    memset(ccount, 0, sizeof(ccount));
    for (register int i(1); i < n - 1; ++i) {
      if (Judge(n, i)) {
        pascal[countt++] = i + 1;
      }
    }
    printf("%d\n", countt);
    for (register int i(0); i < countt; ++i){
      printf(!i ? "%d" : " %d", pascal[i]);
    }
    putchar('\n');
  }
  return 0;
}

原文地址:https://www.cnblogs.com/forth/p/9714248.html

时间: 2024-10-08 02:54:20

UVa 1635 Irrelevant Elements (唯一分解定理 || 组合数学)的相关文章

uva 1635 - Irrelevant Elements

链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=850&problem=4510 题意:一组数字a1,a2,a3.......,不断的相邻数成一组求和形成新的一组,直到最后不可以在合并为止,问最后的答案对m取模与哪些初始的项的无关? 题解:显然无关就是要求某一项在最终的数列中的系数是m的倍数,并且显然最终系列的系数是二项分布

uva1635 Irrelevant Elements(唯一分解定理)

题目链接:点击打开链接 题意:给定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 解题思路: 1.首先我们可以发现对于给定的n其实每项的系数就是C(n-1,i-1),所以我们只需要找到每项的系数对m取余是否为0即可 2.由于m的取值

【UVa1635】Irrelevant Elements - 唯一分解定理

题意 给你 \(n\) 个数,每次求出相邻两个数的和组成新数列.经过 \(n-1\) 次操作后,得到一个数.求这个数 \(mod \ m\) 与哪些项无关. 如:当 \(m=2 \ , \ n=2\) 时 \(a_1 \ , \ a_2 , a_3 \Rightarrow a_1+a_2 \ , \ a_2+a_3 \Rightarrow \ a_1+2a_2+a_3\) 则与 \(a_2\) 无关 思路 由二项式定理知道结果系数是杨辉三角的第 \(n-1\) 行,问题转换成判断有多少个 \(C

UVa 1635 - Irrelevant Elements-[分解质因数]

Young cryptoanalyst Georgie is investigating different schemes of generating random integer numbers ranging from 0 to m − 1. He thinks that standard random number generators are not good enough, so he has invented his own scheme that is intended to b

uva 10375 唯一分解定理 筛法求素数【数论】

唯一分解理论的基本内容: 任意一个大于1的正整数都能表示成若干个质数的乘积,且表示的方法是唯一的.换句话说,一个数能被唯一地分解成质因数的乘积.因此这个定理又叫做唯一分解定理. 举个栗子:50=(2^1)*(5^2) 题目一般的思路就是要把素数表打出来,eg上面的例子 e={1,0,2,0,0......} 下面是两个题目,仅说说大致的思想: 题目一: E=(X1*X3*X4* ...*Xk)/X2   判断E是不是整数 如果把(X1*X3*X4* ...*Xk)分解成素数相乘,将X2也分解成素

uva 10791 Minimum Sum LCM ( 唯一分解定理 )

使用唯一分解定理的时候不一定要打出素数表,这句话是相对上一篇来讲的.做这道题目之前我对唯一分解定理方法的理解不完全. 现在多想到了一些 唯一分解,将当前需要分解的n用因子将其分解表达.需要试因子. 因子的枚举应该是从2开始(从1开始没有意义),当当前数字n可以整除当前因子i时,就使其不断除以i,直到不能整除. 这个步骤实际上已经在根本上避免了出现像4.6这种因子在唯一分解式中的出现--之前的因子2和3已经将其代替了.所以可证明唯一分解时并不一定需要构造素数表 针对本题来说,最小公倍数的最小和,有

UVA 10375 Choose and divide(唯一分解定理)

这么大数的乘法.除法运算,肯定不能先全部乘起来,我的思路是计算出分子.分母上的每个数的个数(因为最大的数为10000,可以开一个数组记录个数). 利用了随机数方法终于知道错在哪了,中间如果出现连乘还是会溢出,这点没想到,以下是我的溢出代码: #include<stdio.h> #include<math.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<

UVA 10375 Choose and divide【唯一分解定理】

题意:求C(p,q)/C(r,s),4个数均小于10000,答案不大于10^8 思路:根据答案的范围猜测,不需要使用高精度.根据唯一分解定理,每一个数都可以分解成若干素数相乘.先求出10000以内的所有素数,用a数组表示唯一分解式中个素数的指数,求出每个分子部分的素因子,并且相应的素数的指数加一.分母则减一.最后求解唯一分解式的值. #include<stdio.h> #include<string.h> #include<math.h> const int N=1e4

Choose and divide UVA - 10375(筛素法+唯一分解定理的应用)

通过题目给的定义C(m,n)=m!/(n!(m-n)!),以及题目要求计算的C(p,q)/C(r,s)联立可得 p!s!(r-s)!/q!r!(p-q)! 看到这个式子,我们可以分析一下,我们可以将每个阶乘,都通过唯一分解定理将它们分解 (具体教程可见:https://blog.csdn.net/qq_39439314/article/details/78270905) 所以,首先我们应该先求出10000以内的所有素数,然后通过唯一分解定理将各个阶乘都分解,求出所有存在的可用质数以及对应的质数的