zoukankan      html  css  js  c++  java
  • UVa 1635

    链接:

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

    题意:

    对于给定的n个数a1, a2,…, an,依次求出相邻两数之和,将得到一个新数列。重复上述操作,最后结果将变成一个数。
    问这个数除以m的余数与哪些数无关?例如n=3,m=2时,第一次求和得到a1+a2,a2+a3,
    再求和得到a1+2a2+a3,它除以2的余数和a2无关。1≤n≤1e5,2≤m≤1e9。

    分析:

    不难证明,在一般情况下,最后ai的系数是C(n-1,i-1)。这样,问题就变成了求C(n-1,0), C(n-1,1), ...,C(n-1,n-1)中
    有哪些是m的倍数。理论上,利用C(n,k) = (n-k+1)/k * C(n,k-1)可以递推出所有C(n-1,i-1),但它们太大了,
    虽然可以用高精度,但是运算会很慢。然而此问题中所关心的只是“哪些是m的倍数”,所以只需要依次计算m的
    唯一分解式中各个素因子在C(n-1,i-1)中的指数即可完成判断。这些指数仍然可以用上式递推,并且不会涉及高精度。

    代码:

     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++) { // 求C(n,0)~C(n,n)有哪些数是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 }
  • 相关阅读:
    pat乙级1018
    下拉框多选,出现这种情况,求大神帮我看看
    Filter 过滤器
    拦截器和过滤器区别
    Servlet 生命周期
    cannot simultaneously fetch multiple bags 问题的解决办法
    JPA规范及其它持久层框架
    数据库设计的三大范式
    装饰者模式
    Java 流
  • 原文地址:https://www.cnblogs.com/hkxy125/p/8903826.html
Copyright © 2011-2022 走看看