2的3100000次幂,暴力法电脑炸了,有什么好算法吗

P1045 [NOIP2003 普及组] 麦森数

hxqy1998 @ 2021-07-20 14:58:54

大数相加、大数相乘已经不适用本题了么

import java.lang.reflect.Field;
import java.util.Scanner;

public class Main{

    private static Scanner in = new Scanner(System.in);

    public static void main(String[] args) {
        int p = in.nextInt();
        String value = cal(p);
        subtractOne(value);
        int len = value.length();
        System.out.println(len);
        if(len < 500) {
            len = 500 - len;
            StringBuilder zero = new StringBuilder(len);
            for (int i = 0; i < len; i++) {
                zero.append('0');
            }
            value = zero.toString() + value;
        }else{
            value = value.substring(len - 500, len);
        }
        for (int i = 0; i < 10; i++) {
            System.out.println(value.substring(i * 50, i * 50 + 50));
        }
    }

    private static String cal(int p){
        if(p < 64) {
            return Long.toString((long)(Math.pow(2, p)));
        }
        String value = cal(p / 2);
        value = multiply(value, value);
        if( (p & 1) == 1 ){
            value = multiply(value, "2");
        }
        return value;
    }

    private static String add(String a, String b){
        if(a.equals("0")) return b;
        if(b.equals("0")) return a;
        if(a.length() < b.length()){
            return add(b, a);
        }
        char[] res = new char[a.length() + 1];
        int index = a.length(), carry = 0, n, ai = a.length() - 1;
        for (int i = b.length() - 1; i >= 0; i--, ai--) {
            n = a.charAt(ai) - '0' + b.charAt(i) - '0' + carry;
            res[index--] = (char)(n % 10 + '0');
            carry = n / 10;
        }
        for (; ai >= 0; ai--) {
            n = a.charAt(ai) - '0' + carry;
            res[index--] = (char)(n % 10 + '0');
            carry = n / 10;
        }
        if(carry == 1) {
            res[0] = '1';
            return new String(res);
        }
        return new String(res, 1, a.length());
    }
    private static String multiply(String a, String b){
        if(a.equals("0") || b.equals("0")) return "0";
        if(a.length() < b.length()){
            return multiply(b, a);
        }
        int carry = 0, bit = 0, bb, n;
        String last = "0";
        for (int i = b.length() - 1; i >= 0; i--, bit++) {
            if(b.charAt(i) != '0') {
                char[] res = new char[a.length() + 1 + bit];
                int index = a.length();
                for (int j = 1; j <= bit; j++) {
                    res[index + j] = '0';
                }
                bb = b.charAt(i) - '0';
                for (int j = a.length() - 1; j >= 0; j--) {
                    n = (a.charAt(j) - '0') * bb + carry;
                    res[index--] = (char)(n % 10 + '0');
                    carry = n / 10;
                }
                if(carry > 0) {
                    res[0] = (char)(carry + '0');
                    last = add(last, new String(res));
                }else{
                    last = add(last, new String(res, 1, res.length - 1));
                }
                carry = 0;
            }
        }
        return last;
    }
    private static void subtractOne(String a){
        try {
            Field f = a.getClass().getDeclaredField("value");
            f.setAccessible(true);
            char[] values = (char[])f.get(a);
            if(values[values.length - 1] >= '1'){
                values[values.length - 1] -= 1;
            }else {
                for (int i = values.length - 2; i >= 0; i--) {
                    if(values[i] >= '1'){
                        values[i] -= 1;
                        for (int j = i + 1; j < values.length; j++) {
                            values[j] = '9';
                        }
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

by Lightwhite @ 2021-07-20 15:09:46

建议快速幂,可以参考模板。


by _8762 @ 2021-07-20 15:09:53

用科大讯飞的超算机 无论复杂度多少都不会爆炸


by hmya @ 2021-07-20 15:13:03

打表?


by hmya @ 2021-07-20 15:40:24

@hxqy1998 用python?


by hxqy1998 @ 2021-08-19 15:25:09

@蒋金洲

2^9 = (2^4)^2 * 2 = ((2^2)^2)^2 * 2 = ……

是类似这样的吗?


by hxqy1998 @ 2021-08-19 15:26:20

@潜在了H2O下面 万能的打表哈哈哈


by Lightwhite @ 2021-08-19 16:26:42

是的


|