• SPOJ DIVSUM2 PollardRho 康某


    大意:给出一个数,求他的所有因子的和(不包括自己)

    首先,先算上他自己,问题转化为求所有因子的和

    根据唯一分解定理,设数为N,则质因子为P1P2...PK,指数设为A1A2...AK

    则所有因子,则是P1位指数取【0,A1】,P2位取【0,A2】…………

    譬如20 = 2 ^2 * 5,则因子为 1(2^0 * 5^0),2(2^1 * 5 * 0),4(2 ^ 2 * 5 ^ 0),5(2^0 * 5 ^ 1),10(2^1 * 5 ^ 1),20(2^2* 5 ^ 1)

    提取一下 = 2^0 *(5 ^ 0 + 5 ^ 1) + 2^1 *(5 ^ 0 + 5 ^ 1) + 2^2 *(5 ^ 0 + 5 ^ 1)

    = (2 ^ 0 + 2 ^ 1 + 2 ^ 2) * (5 ^ 0 + 5 ^ 1) = 42

    挺对……于是公式可以得出……就是每个因子等比序列求和一下,然后求乘积得到所有因子相加的和,最后减去N自己即可……

    问题在于怎么质因子分解……这个数很大,很难做……于是,我们要使用 PollardRho 算法……

    另外有一点要注意……Java不是没有函数传地址……Java相当于传的是个Vector* ret,如果你想修改他,ret = XXX 是没戏的…… 而ret.set(XXX)是正解……

    见第33行……

    分解之后,排序,统计即可

     1 import java.math.BigInteger;
     2 import java.security.SecureRandom;
     3 import java.io.*;
     4 import java.util.*;
     5 
     6 
     7 
     8 class PollardRho {
     9     private final static BigInteger ZERO = new BigInteger("0");
    10     private final static BigInteger ONE  = new BigInteger("1");
    11     private final static BigInteger TWO  = new BigInteger("2");
    12     private final static SecureRandom random = new SecureRandom();
    13 
    14     public static BigInteger rho(BigInteger N) {
    15         BigInteger divisor;
    16         BigInteger c  = new BigInteger(N.bitLength(), random);
    17         BigInteger x  = new BigInteger(N.bitLength(), random);
    18         BigInteger xx = x;
    19 
    20         // check divisibility by 2
    21         if (N.mod(TWO).compareTo(ZERO) == 0) return TWO;
    22 
    23         do {
    24             x  =  x.multiply(x).mod(N).add(c).mod(N);
    25             xx = xx.multiply(xx).mod(N).add(c).mod(N);
    26             xx = xx.multiply(xx).mod(N).add(c).mod(N);
    27             divisor = x.subtract(xx).gcd(N);
    28         } while((divisor.compareTo(ONE)) == 0);
    29 
    30         return divisor;
    31     }
    32 
    33     public static void factor(BigInteger N, Vector<Long> ret) {
    34         if (N.compareTo(ONE) == 0) return;
    35         if (N.isProbablePrime(20)) { ret.add(N.longValue()); return; }
    36         BigInteger divisor = rho(N);
    37         factor(divisor,ret);
    38         factor(N.divide(divisor),ret);
    39     }
    40 }
    41 
    42 class Main {
    43     public static void main(String args[]) {
    44         new Main().work();
    45     }
    46 
    47     void factor(int n, Vector<Long> ret) {
    48     }
    49 
    50     void work() {
    51         try {
    52             BufferedReader in = new BufferedReader(
    53                     new InputStreamReader(System.in));
    54             int nn = Integer.parseInt(in.readLine());
    55             while (nn-- > 0) {
    56                 long n = Long.parseLong(in.readLine());
    57                 Vector<Long> ret = new Vector<Long>();
    58                 PollardRho.factor(BigInteger.valueOf(n),ret);
    59                 Collections.sort(ret);
    60                 // System.err.println(ret);
    61 
    62                 Long ans = 1L;
    63                 for (int i = 0; i < ret.size(); i++) {
    64                     Long pow = 1L;
    65                     Long sum = 1L;
    66                     for (int j = i; j < ret.size() && ret.get(j).equals(ret.get(i));j++) {
    67                         pow *= ret.get(j);
    68                         sum += pow;
    69                         i = j;
    70                     }
    71                     // System.err.printf("%d %d\n",pow,sum);
    72                     ans *= sum;
    73                 }
    74                 System.out.println(ans - n);
    75             }
    76         } catch (Exception e) {}
    77     }
    78 }
  • 相关阅读:
    团队协议
    C++ 多继承和虚继承的内存布局(转)
    轻量级的.Net ORM框架介绍
    EF下CodeFirst、DBFirst与ModelFirst分析
    JDK方式
    JSON
    事务的ACID特性
    数据库查询
    Assets
    内部文件存储
  • 原文地址:https://www.cnblogs.com/sweetsc/p/2580991.html
Copyright © 2020-2023  润新知