fork download
/*
プログラミングのお題スレ Part12 
//mevius.5ch.net/test/read.cgi/tech/1538096947/17
 
17 名前:デフォルトの名無しさん[] 投稿日:2018/10/01(月) 20:03:33.29 ID:IziOBEHB
お題:f(n)::={nを連続するいくつかの正整数の和として表す表し方の総数}とおく
例えば、15=7+8=4+5+6=1+2+3+4+5よりf(15)=4である
上限Nが与えられたとき、n<=Nでf(n)が奇数となるようなnをすべて足し合わせた値を求めよ
 
10 -> 24
100 -> 665
1000 -> 18006
10000 -> 571940
100000 -> 18010994
1000000 -> 569929080
10000000 -> 18001029437
100000000 -> 569128815672
1000000000 -> 17994029079715
*/
 
class Ideone
{
    public static void main(String[] args)
    {
        solve(10);
        solve(100);
        solve(1000);
        solve(10000);
        solve(100000);
        solve(1000000);
        solve(10000000);
        solve(100000000);
        solve(1000000000);
    }
    
    
    static final int MAX = Integer.MAX_VALUE;
    static final int[] factor;
    static
    {
        int[] temp = new int[(int) Math.sqrt(MAX)];
        temp[0] = 2;
        int n = 1;
        loop: for (int i = 3, j = (int) Math.sqrt(MAX); i <= j; i += 2) {
            for (int k = 3, l = (int) Math.sqrt(i); k <= l; k += 2) {
                if (i % k == 0) continue loop;
            }
            temp[n++] = i * i;
        }
        factor = java.util.Arrays.copyOf(temp, n);
    }
    
    static void solve(int n)
    {
        if (n < 1) throw new IllegalArgumentException();
        System.out.printf("%d -> %d%n", n, r(n, 1, 0));
    }

    private static long r(int n, long cur, int f)
    {
        long ret = cur;
        for (int i = f; i < factor.length && cur * factor[i] <= n; i++) {
            ret += r(n, cur * factor[i], i);
        }
        return ret;
    }
}
Success #stdin #stdout 0.05s 2184192KB
stdin
Standard input is empty
stdout
10 -> 24
100 -> 665
1000 -> 18006
10000 -> 571940
100000 -> 18010994
1000000 -> 569929080
10000000 -> 18001029437
100000000 -> 569128815672
1000000000 -> 17994029079715