[伯努利数] poj 1707 Sum of powers

题目链接:

http://poj.org/problem?id=1707


Language:
Default

Sum of powers

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 735   Accepted: 354

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

Northeastern Europe 1997

题目意思:

已知并且求最小的M,使得a[k+1]---a[0]都为整数。

解题思路:

伯努利数:http://zh.wikipedia.org/wiki/%E4%BC%AF%E5%8A%AA%E5%88%A9%E6%95%B0

所以有1^k+2^k+3^k+...+n^k=1/(k+1)(C[k+1,0)*B[0]*n^(k+1-0)+C[k+1,1]*B[1]*n^(k+1-1)+...+C[k+1,j]*B[j]*n^(k+1-j)+...+C[k+1,k]*B[k]*n^(k+1-k))+n^k

先求出伯努利数,然后分母求最小公倍数即可。

注意n^k的系数要加上后面的n^k为C[k+1,1]*B[1]+(k+1)

最后只剩下分数加法了。注意最大公约数为负数的情况,强制转化为正数,用分子保存整个分数的正负性。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 25
ll C[Maxn][Maxn];
struct PP
{
    ll a,b;
}B[Maxn],ans[Maxn];

ll k;

ll gcd(ll a,ll b)
{
    if(a%b==0)
    {
        if(b>0)
            return b;
        return -b;
    }

    return gcd(b,a%b);
}

PP add(PP a,PP b) //模拟两个分数的加法
{
    if(!a.a) //如果有一个为0
        return b;
    if(!b.a)
        return a;

    ll temp=a.b/gcd(a.b,b.b)*b.b; //求出分母的最小公倍数
    //printf("%I64d\n",temp);
    PP res;
    res.a=temp/a.b*a.a+temp/b.b*b.a; //分子相加
    res.b=temp;

    if(res.a)  //约掉最大公约数
    {
        ll tt=gcd(res.a,res.b);
        res.b/=tt;
        res.a/=tt;
    }
    return res;

}

void init()
{
    memset(C,0,sizeof(C));

    for(int i=0;i<=25;i++)
    {
        C[i][0]=1;
        for(int j=1;j<i;j++)
            C[i][j]=C[i-1][j]+C[i-1][j-1];
        C[i][i]=1;
    }
    B[0].a=1,B[0].b=1;  //求伯努利数

    for(int i=1;i<=20;i++)  //用递推关系求
    {
        PP temp;
        temp.a=0;
        temp.b=0;

        for(int j=0;j<i;j++)
        {
            PP tt=B[j];

            tt.a=tt.a*C[i+1][j];
            //printf("::::%I64d %I64d:\n",tt.a,tt.b);
            if(tt.a)
            {
                ll te=gcd(tt.a,tt.b);
                tt.a/=te;
                tt.b/=te;
            }

            temp=add(temp,tt);

            //printf("i:%d j:%d %I64d %I64d:\n",i,j,temp.a,temp.b);
            //system("pause");
        }

        temp.a=-temp.a;
        temp.b*=C[i+1][i];
        //printf("%I64d %I64d\n",temp.a,temp.b);
        //system("pause");

        //printf("%I64d\n",gcd(temp.a,temp.b));
        if(temp.a)
        {
            ll te=gcd(temp.a,temp.b);
            temp.a/=te;
            temp.b/=te;
        }
        else
            temp.b=0;
        B[i]=temp;
        //printf("i:%d %I64d %I64d\n",i,B[i].a,B[i].b);
        //system("pause");
    }
}

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);

   //printf("%I64d\n",gcd(-6,12));

   init();
   while(~scanf("%I64d",&k))
   {

       ll cur=1;

       for(int i=0;i<=k;i++)
       {
           if(i==1)
           {
               ans[i].a=k+1;  //B[1]=-1/2要加上后面多出来的n^k
               ans[i].b=2;
           }
           else
           {
               ans[i]=B[i];
               ans[i].a*=C[k+1][i];
           }

           if(ans[i].a) //约分
           {
               ll temp=gcd(ans[i].a,ans[i].b);
               ans[i].a/=temp;
               ans[i].b/=temp;
           }
           else
                ans[i].b=0;
           if(ans[i].b) //求分母的最小公倍数
                cur=cur/gcd(cur,ans[i].b)*ans[i].b;

       }
       printf("%I64d ",cur*(k+1));
       //printf("->%I64d %I64d %I64d\n",cur,ans[0].a,ans[0].b);
       for(int i=0;i<=k;i++) //求出通分后每一个系数
       {
           if(ans[i].b)
               ans[i].a=cur/ans[i].b*ans[i].a;
               //printf("i:%d %I64d\n",i,ans[i].a);
       }
       for(int i=0;i<=k;i++)
            printf("%I64d ",ans[i].a);
       printf("0\n"); //最后一个肯定是0
   }
   return 0;
}

[伯努利数] poj 1707 Sum of powers,布布扣,bubuko.com

时间: 2024-12-09 16:35:15

[伯努利数] poj 1707 Sum of powers的相关文章

UVA 766 - Sum of powers(伯努利数)

766 - Sum of powers 题意:求    转化成 的各系数 思路:在wiki看了伯努利数的性质,  可以推成 . 然后B为伯努利数,有公式, 如此一来就可以去递推求出每项伯努利数了,然后在根据n去通分,求出每一项的答案,中间过程用到了分数的运算. 代码: #include <stdio.h> #include <string.h> long long gcd(long long a, long long b) { if (!b) return a; return gc

POJ 3132 Sum of Different Primes DP背包

http://poj.org/problem?id=3132 题意: 给定n和k,问用恰好k个不同的质数来表示n的方案数. 分析: n和k都很小.反正就是个背包,选k个物品恰好填满n即可. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 bool dp[1200][15]; 6 int ct[1200][15]; 7 int p[1200]; 8 bool a[1200]; 9 int n, k,

POJ 1775 sum of Factorial (数论)

链接:http://poj.org/problem?id=1775 Description John von Neumann, b. Dec. 28, 1903, d. Feb. 8, 1957, was a Hungarian-American mathematician who made important contributions to the foundations of mathematics, logic, quantum physics,meteorology, science,

POJ 1564 Sum It Up (DFS+剪枝)

 Sum It Up Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5820   Accepted: 2970 Description Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t = 4

zoj 2358,poj 1775 Sum of Factorials(数学题)

题目poj 题目zoj //我感觉是题目表述不确切,比如他没规定xi能不能重复,比如都用1,那么除了0,都是YES了 //算了,这种题目,百度来的过程,多看看记住就好 //题目意思:判断一个非负整数n能否表示成几个数的阶乘之和 //这里有一个重要结论:n!>(0!+1!+……+(n-1)!), //证明很容易,当i<=n-1时,i!<=(n-1)!,故(0!+1!+……+(n-1)!)<=n*(n-1)!=n!. // 由于题目规定n<=1000000,而10!=362880

ACM:POJ 2739 Sum of Consecutive Prime Numbers-素数打表-尺取法

POJ 2739 Sum of Consecutive Prime Numbers Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description Some positive integers can be represented by a sum of one or more consecutive prime numbers. How many such representation

POJ 1730 Perfect Pth Powers (枚举||分解质因子)

Perfect Pth Powers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16638   Accepted: 3771 Description We say that x is a perfect square if, for some integer b, x = b2. Similarly, x is a perfect cube if, for some integer b, x = b3. More g

uva 766 - Sum of powers(数学+递推)

题目连接:uva 766 - Sum of powers 题目大意:将Sk(n)=∑i=1nik化简成Sk(n)=ak+1nk+1+aknk+?+a0M 解题思路: 已知幂k,并且有(n+1)k=C(kk)nk+C(k?1k)nk?1+?+C(0k)n0结论. 所以令 (n+1)k+1?nk+1=C(kk+1)nk+C(k?1k+1)nk?1+?+C(0k+1)n0 nk+1?(n?1)k+1=C(kk+1)(n?1)k+C(k?1k+1)(n?1)k?1+?+C(0k+1)(n?1)0 - 2

UVA766 Sum of powers(1到n的自然数幂和 伯努利数)

自然数幂和: (1) 伯努利数的递推式: B0 = 1 (要满足(1)式,求出Bn后将B1改为1 /2) 参考:https://en.wikipedia.org/wiki/Bernoulli_number http://blog.csdn.net/acdreamers/article/details/38929067 使用分数类,代入求解 #include<cstdio> #include<iostream> #include<cstdlib> #include<