码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 1864 自然数幂和

时间:2015-01-26 10:20:12      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:数论   自然数幂和   

zoj 1864

题目链接:

点击打开链接

题意:

求自然数幂和。
限制:
0 <= n <= 10^50; 1 <= k <= 100
思路:
k不大,而且答案不取模,直接搞
(n+1)^(k+1) - n^(k+1) = C(k+1,1)*n^k + C(k+1,2)*n^(k-1) + ... + C(k+1,k)*n + 1;
(n+1)^(k+1) - 1 = ( (n+1)^(k+1) - n^(k+1) ) + ( n^(k+1) - (n-1)^(k+1) ) + ... + ( 2^(k+1) - 1^(k+1) )
=C(k+1,1)*(1^k+2^k+...+n^k) + C(k+1,2)*(1^(k-1)+2^(k-1)+...+n^(k-1)) + C(k+1,k)*(1+2+...+n) + n;
令S(k,n)=1^k+2^k+...+n^k 得:
(n+1)^(k+1) - 1 = C(k+1,1)*S(k,n) + C(k+1,2)*S(k-1,n) + ... + C(k+1,k)*S(1,n) + n;
移项得:
C(k+1,1)*S(k,n) = ...
S(k,n) = 1/C(k+1,1) * ...
能O(k^2)得出结果

其实也可以用伯努利数来做。


 Java Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*zoj 1864
  题意:
  求自然数幂。
  限制:
  0 <= n <= 10^50; 1 <= k <= 100
  思路:
  k不大,而且答案不取模,直接搞
  (n+1)^(k+1) - n^(k+1) = C(k+1,1)*n^k + C(k+1,2)*n^(k-1) + ... + C(k+1,k)*n + 1;
  (n+1)^(k+1) - 1 = ( (n+1)^(k+1) - n^(k+1) ) + ( n^(k+1) - (n-1)^(k+1) ) + ... + ( 2^(k+1) - 1^(k+1) )
  =C(k+1,1)*(1^k+2^k+...+n^k) + C(k+1,2)*(1^(k-1)+2^(k-1)+...+n^(k-1)) + C(k+1,k)*(1+2+...+n) + n;
  令S(k,n)=1^k+2^k+...+n^k 得:
  (n+1)^(k+1) - 1 = C(k+1,1)*S(k,n) + C(k+1,2)*S(k-1,n) + ... + C(k+1,k)*S(1,n) + n;
  移项得:
  C(k+1,1)*S(k,n) = ...
  S(k,n) = 1/C(k+1,1) * ...
  能O(k^2)得出结果
  其实也可以用伯努利数来做。
  */

import java.math.BigInteger;
import java.util.Scanner;

public class Main
{
    static final int N = 105;
    static final BigInteger _one = BigInteger.valueOf(-1);
    static BigInteger[][] C = new BigInteger[N][N];
    static BigInteger[] ans = new BigInteger[N];
    static BigInteger[] n1k1 = new BigInteger[N];

    static void predo()
    {
        for(int i = 0; i < N; ++i)
            C[i][0] = C[i][i] = BigInteger.ONE;
        for(int i = 2; i < N; ++i)
            for(int j = 1; j < i; ++j)
                C[i][j] = C[i - 1][j].add(C[i - 1][j - 1]);
    }

    static void init(BigInteger n, int k)
    {
        for(int i = 0; i <= k; ++i)
            ans[i] = _one;
        n1k1[0] = n.add(BigInteger.ONE);
        for(int i = 1; i <= k; ++i)
            n1k1[i] = n1k1[i - 1].multiply(n.add(BigInteger.ONE));
    }

    static BigInteger gao(BigInteger n, int k)
    {
        if(!ans[k].equals(_one))
            return ans[k];
        if(k == 1)
            ans[k] = n.add(BigInteger.ONE).multiply(n).divide(BigInteger.valueOf(2));
        else
        {
            ans[k] = n1k1[k].subtract(n.add(BigInteger.ONE));
            for(int i = 2; i <= k; ++i)
                ans[k] = ans[k].subtract(C[k + 1][i].multiply(gao(n, k - i + 1)));
            ans[k] = ans[k].divide(BigInteger.valueOf(k + 1));
        }
        return ans[k];
    }

    public static void main(String[] args)
    {
        predo();
        Scanner in = new Scanner(System.in);
        BigInteger n;
        int k;
        while (in.hasNext())
        {
            n = in.nextBigInteger();
            k = in.nextInt();
            init(n, k);
            System.out.println(gao(n, k));
        }
    }
}

zoj 1864 自然数幂和

标签:数论   自然数幂和   

原文地址:http://blog.csdn.net/whai362/article/details/43148797

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!