[伯努利数] poj 1707 Sum of powers
题目链接:
http://poj.org/problem?id=1707
| Language: Default 
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 | 
题目意思:
已知而且
求最小的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的更多相关文章
- POJ 1707 Sum of powers(伯努利数)
		题目链接:http://poj.org/problem?id=1707 题意:给出n 在M为正整数且尽量小的前提下,使得n的系数均为整数. 思路: i64 Gcd(i64 x,i64 y) { if( ... 
- ACM:POJ 2739 Sum of Consecutive Prime Numbers-素数打表-尺取法
		POJ 2739 Sum of Consecutive Prime Numbers Time Limit:1000MS Memory Limit:65536KB 64bit IO Fo ... 
- [CSAcademy]Sum of Powers
		[CSAcademy]Sum of Powers 题目大意: 给定\(n,m,k(n,m,k\le4096)\).一个无序可重集\(A\)为合法的,当且仅当\(|A|=m\)且\(\sum A_i=n ... 
- POJ.2739 Sum of Consecutive Prime Numbers(水)
		POJ.2739 Sum of Consecutive Prime Numbers(水) 代码总览 #include <cstdio> #include <cstring> # ... 
- POJ 2739 Sum of Consecutive Prime Numbers(素数)
		POJ 2739 Sum of Consecutive Prime Numbers(素数) http://poj.org/problem? id=2739 题意: 给你一个10000以内的自然数X.然 ... 
- Euler's Sum of Powers Conjecture
		转帖:Euler's Sum of Powers Conjecture 存不存在四个大于1的整数的五次幂恰好是另一个整数的五次幂? 暴搜:O(n^4) 用dictionary:O(n^3) impor ... 
- 【POJ1707】【伯努利数】Sum of powers
		Description A young schoolboy would like to calculate the sum for some fixed natural k and different ... 
- UVA766 Sum of powers(1到n的自然数幂和 伯努利数)
		自然数幂和: (1) 伯努利数的递推式: B0 = 1 (要满足(1)式,求出Bn后将B1改为1 /2) 参考:https://en.wikipedia.org/wiki/Bernoulli_numb ... 
- UVa 766 Sum of powers (伯努利数)
		题意: 求 ,要求M尽量小. 析:这其实就是一个伯努利数,伯努利数公式如下: 伯努利数满足条件B0 = 1,并且 也有 几乎就是本题,然后只要把 n 换成 n-1,然后后面就一样了,然后最后再加上一个 ... 
随机推荐
- Python之获取文件夹中文件列表以及glob与fnmatch模块的使用
			获取文件夹中的文件列表 print(os.listdir("../secondPackage")) # ['__init__.py', 'secondCookBook.py', ' ... 
- Dubbo源码学习总结系列二 dubbo-rpc远程调用模块
			dubbo本质是一个RPC框架,我们首先讨论这个骨干中的骨干,dubbo-rpc模块. 主要讨论一下几部分内容: 一.此模块在dubbo整体框架中的作用: 二.此模块需要完成的需求功能点及接口定义: ... 
- SpringBoot中Redis的使用
			转载:http://www.ityouknow.com/springboot/2016/03/06/spring-boot-redis.html Spring Boot 对常用的数据库支持外,对 No ... 
- spark大数据快速分析第二章
			1.驱动程序通过一个SparkContext对象来访问Spark,此对象代表对计算集群的一个连接.shell已经自动创建了一个SparkContext对象.利用SparkContext对象来创建一个R ... 
- C#基础提升系列——C# 泛型
			C# 泛型(Generics) 泛型概述 泛型是C#编程语言的一部分,它与程序集中的IL(Intermediate Language,中间语言)代码紧密的集成.通过泛型,我们不必给不同的类型编写功能相 ... 
- pycharm  html  注释
			修改方式:如图修改成值None以后,command+/快捷键,html注释的符号就是<!-- 注释内容 -->:为Jinja2的时候,注释符号就是{# 注释内容 #} 修改成None时,H ... 
- Echarts--Y坐标标题显示不全
			如:下图,Y坐标标题显示不全 y2可以控制不显示区域的高度,就能显示全啦 grid:{ x:40, x2:100, y2:200 } 
- promise函数
			一.promise函数是干什么的 promise函数是解决异步编程调用代码逻辑编写过于复杂的问题的,当网络请求非常复杂时,就会出现回调地狱,这样如果将这些代码写在一起就会看起来很复杂,且不利于阅读,如 ... 
- Jenkins之配置GitHub-Webhook2
			什么是持续集成(Continuous integration) 提出者Martin Fowler本人对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每 ... 
- yii2.0增删改查实例讲解
			yii2.0增删改查实例讲解一.创建数据库文件. 创建表 CREATE TABLE `resource` ( `id` int(10) NOT NULL AUTO_INCREMENT, `textur ... 
