UVa 1635 - Irrelevant Elements (Binomial Coefficients + Unique Decomposition Theorem)

Link:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4510

 

Title:

For a given n numbers a1, a2,..., an, find the sum of two adjacent numbers in turn, and a new sequence will be obtained. Repeat the above operation, the final result will become a number.
What is the remainder of dividing this number by m? For example, when n=3 and m=2, the first summation obtains a1+a2, a2+a3,
and then the summation obtains a1+2a2+a3. The remainder of dividing it by 2 has nothing to do with a2. 1≤n≤1e5, 2≤m≤1e9.

 

analyze:

It is not difficult to prove that, in the general case, the coefficient of the last ai is C(n-1,i-1). In this way, the problem becomes to find which of C(n-1,0), C(n-1,1), ..., C(n-1,n-1) are
multiples of m. In theory, all C(n-1,i-1) can be recursively derived using C(n,k) = (n-k+1)/k * C(n,k-1), but they are too large,
High precision is required to save. But the only concern in this question is "which are multiples of m", so it is only necessary to calculate the exponents of each prime factor in C(n-1, i-1) in the unique decomposition formula of m
to complete the judgment. These exponents can still be recursively used above, and no high precision is involved.

 

Code:

 1 import java.io.*;
 2 import java.util.*;
 3 
 4 public class Main {
 5     static ArrayList<Integer> prime = new ArrayList<Integer>();
 6     
 7     static void resolve(int m) {
 8         int u = (int)Math.sqrt(m + 0.5);
 9         for(int i = 2; i <= u; i++) {
10             if(m % i != 0) continue;
11             prime.add(i);
12             while(m % i == 0) m /= i;
13         }
14         if(m > 1) prime.add(m);
15     }
16     
17     public static void main(String args[]) {
18         Scanner cin = new Scanner(new BufferedInputStream(System.in));
19         
20         while(cin.hasNext()) {
21             int n = cin.nextInt();
22             int m = cin.nextInt();
23             
24             n--;
25              boolean bad[] = new  boolean [n+5 ];
 26              prime.clear();
 27              resolve(m);
 28              for ( int t = 0; t < prime.size(); t++) { // find C (n,0)~C(n,n) which numbers are multiples of m 
29                  int p = prime.get(t), e = 0, x = m, min = 0; // C(n,i) = p^e 
30                  while (x % p == 0) { x /= p; min++ ; }
 31                  for ( int k = 1; k < n; k++) { // C(n,k)=C(n ,k-1)*(n-k+1)/k 
32                      x = n - k + 1 ;
 33                     while(x % p == 0) { x /= p;  e++; }
34                     x = k;
35                     while(x % p == 0) { x /= p;  e--; }
36                     if(e < min) bad[k] = true;
37                 }
38             }
39             
40             ArrayList<Integer> ans = new ArrayList<Integer>();
41             for(int i = 1; i < n; i++) if(!bad[i]) ans.add(i+1);
42             System.out.println(ans.size());
43             if(ans.size() > 0) {
44                 System.out.print(ans.get(0));
45                 for(int i = 1; i < ans.size(); i++)
46                     System.out.print(" " + ans.get(i));
47             }
48             System.out.println();
49         }
50         cin.close();
51     }
52 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324590059&siteId=291194637