• 【POJ1707】【伯努利数】Sum of powers


    Description

    A young schoolboy would like to calculate the sum

    for some fixed natural k and different natural n. He observed that calculating ik for all i (1<=i<=n) and summing up results is a too slow way to do it, because the number of required arithmetical operations increases as n increases. Fortunately, there is another method which takes only a constant number of operations regardless of n. It is possible to show that the sum Sk(n) is equal to some polynomial of degree k+1 in the variable n with rational coefficients, i.e.,

    We require that integer M be positive and as small as possible. Under this condition the entire set of such numbers (i.e. M, ak+1, ak, ... , a1, a0) will be unique for the given k. You have to write a program to find such set of coefficients to help the schoolboy make his calculations quicker.

    Input

    The input file contains a single integer k (1<=k<=20).

    Output

    Write integer numbers M, ak+1, ak, ... , a1, a0 to the output file in the given order. Numbers should be separated by one space. Remember that you should write the answer with the smallest positive M possible.

    Sample Input

    2

    Sample Output

    6 2 3 1 0
    

    Source

    【分析】
    题意就是给出一个k,找一个最小的M使得中a[i]皆为整数.
    这个涉及到伯努利数的一些公式,如果不知道的话基本没法做..

    1. 伯努利数与自然数幂的关系:

    2. 伯努利数递推式:


    先通过递推式求得伯努利数,然后用1公式并将中间的(n+1) ^ i,变成n ^ i,后面再加上n ^ k,化进去就行了。
     1 /*
     2 宋代朱敦儒
     3 《西江月·世事短如春梦》
     4 世事短如春梦,人情薄似秋云。不须计较苦劳心。万事原来有命。
     5 幸遇三杯酒好,况逢一朵花新。片时欢笑且相亲。明日阴晴未定。 
     6 */
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <cmath>
    11 #include <queue>
    12 #include <vector>
    13 #include <iostream>
    14 #include <string>
    15 #include <ctime>
    16 #define LOCAL
    17 const int MAXN = 20 + 10;
    18 const double Pi = acos(-1.0);
    19 using namespace std;
    20 typedef long long ll;
    21 ll gcd(ll a, ll b){return b == 0? a: gcd(b, a % b);} 
    22 struct Num{
    23        ll a, b;//分数,b为分母 
    24        Num(ll x = 0, ll y = 0) {a = x;b = y;}
    25        void update(){
    26            ll tmp = gcd(a, b);
    27            a /= tmp;
    28            b /= tmp;
    29        }
    30        Num operator + (const Num &c){
    31            ll fz = a * c.b + b * c.a, fm = b * c.b;
    32            if (fz == 0) return Num(0, 1);
    33            ll tmp = gcd(fz, fm);
    34            return Num(fz / tmp, fm / tmp);
    35        } 
    36 }B[MAXN], A[MAXN];
    37 ll C[MAXN][MAXN];
    38 
    39 void init(){
    40      //预处理组合数 
    41      for (int i = 0; i < MAXN; i++) C[i][0] = C[i][i] = 1;
    42      for (int i = 2; i < MAXN; i++)
    43      for (int j = 1; j < MAXN; j++) C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    44      //预处理伯努利数 
    45      B[0] = Num(1, 1);
    46      for (int i = 1; i < MAXN; i++){
    47          Num tmp = Num(0, 1), add;
    48          for (int j = 0; j < i; j++){
    49              add = B[j];
    50              add.a *= C[i + 1][j];
    51              tmp = tmp + add;
    52          }
    53          if (tmp.a) tmp.b *= -(i + 1);
    54          tmp.update();
    55          B[i] = tmp;
    56      } 
    57 }
    58 void work(){
    59      int n;
    60      scanf("%d", &n);
    61      ll M = n + 1, flag = 0, Lcm;
    62      A[0] = Num(0, 1);
    63      for (int i = 1; i <= n + 1; i++){
    64          if (B[n + 1 - i].a == 0) {A[i] = Num(0, 1);continue;}
    65          Num tmp = B[n + 1 - i];
    66          tmp.a *= C[n + 1][i];//C[n+1][i] = C[n + 1][n + 1 - i]
    67          tmp.update();
    68          if (flag == 0) Lcm = flag = tmp.b;
    69          A[i] = tmp;
    70      }
    71      A[n] = A[n] + Num(n + 1, 1);
    72      
    73      for (int i = 2; i <= n + 1; i++){
    74          if (A[i].a == 0) continue;
    75          Lcm = (Lcm * A[i].b) / gcd(Lcm, A[i].b);
    76      }
    77      if (Lcm < 0) Lcm *= -1;
    78      M *= Lcm;
    79      printf("%lld", M);
    80      for (int i = n + 1; i >= 0; i--) printf(" %lld", A[i].a * Lcm / A[i].b); 
    81 }
    82 
    83 int main(){
    84     
    85     init();
    86     work();
    87     //printf("%lld
    ", C[5][3]);
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    [转]find高级用法
    svn服务器配置
    awk (一)
    Linux下恢复ext3文件系统误删除文件ext3grep
    cobbler无人值守安装操作系统
    Linux下virtualbox网络配置
    nginx+uwsgi来部署Django
    solaris 网络设置
    rpm 使用说明
    linux 下安装mysql
  • 原文地址:https://www.cnblogs.com/hoskey/p/4379935.html
Copyright © 2020-2023  润新知