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<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 25, INF = 0x3F3F3F3F;

LL gcd(LL a, LL b){
    while(b){
        LL t = a % b;
        a = b;
        b = t;
    }
    return a;
}

LL lcm(LL a, LL b){
    return a / gcd(a, b) * b;
}

struct frac{
	LL x, y;
	frac(){
		x = 0;
		y = 1;
	}
	frac(LL x1, LL y1){
		x = x1;
		y = y1;
	}
	frac operator*(const frac &tp)const{
		LL a = x * tp.x;
		LL b = y * tp.y;
		LL d = gcd(a, b);
		a /= d;
		b /= d;
		if(a >= 0 && b < 0){
            a = -a;
            b = -b;
		}
		return frac(a, b);
	}

	frac operator+(const frac &tp)const{
		LL a = x * tp.y + tp.x * y;
		LL b = y * tp.y;
		LL d = gcd(a, b);
		a /= d;
		b /= d;
		if(a >= 0 && b < 0){
            a = -a;
            b = -b;
		}

		return frac(a, b);
	}

}ans[N][N], bo[N];

LL cm[N][N];
void init(){
	memset(cm, 0, sizeof(cm));
	cm[0][0] = 1;
	for(int i = 1; i < N; i++){
		cm[i][0] = 1;
		for(int j = 1; j <= i; j++){
			cm[i][j] = cm[i - 1][j - 1] + cm[i - 1][j];
		}
	}

	bo[0].x = 1, bo[0].y = 1;
	for(int i = 1; i < N; i++){
		bo[i].x = 0;
		bo[i].y = 1;
		for(int j = 0; j < i; j++){
			bo[i] = bo[i] + frac(cm[i + 1][j], 1) * bo[j];
		}
		bo[i] = bo[i] * frac(-1, i + 1);
	}
	bo[1].x = 1; bo[1].y = 2;
	for(int m = 0; m < N; m++){
		for(int k = 0; k <= m; k++){
			ans[m][m + 1 - k] = frac(cm[m + 1][k], 1) * bo[k] * frac(1, m + 1);
		}
		LL lc = ans[m][0].y;
		for(int k = 1; k <= m; k++){
			lc = lcm(ans[m][k].y, lc);
		}
		for(int k = 0; k <= m + 1; k++){
            LL d = lc / ans[m][k].y;
            ans[m][k].x *= d;
            ans[m][k].y *= d;
		}
	}

}

int main(){
    init();
    int t;
    cin >> t;
    while(t--){
    	int n;
    	cin >>n;
    	printf("%lld ", ans[n][0].y);
    	for(int i = n + 1; i >= 0; i--){
    		if(i == 0){
    			printf("%lld\n", ans[n][i].x);
    		}else{
    			printf("%lld ", ans[n][i].x);
    		}
    	}
        if(t){
            printf("\n");
        }
    }

    return 0;
}

  

时间: 2024-10-10 08:04:26

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

[伯努利数] 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

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

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

Codeforces 622F The Sum of the k-th Powers ( 自然数幂和、拉格朗日插值法 )

题目链接 题意 : 就是让你求个自然数幂和.最高次可达 1e6 .求和上限是 1e9 分析 :  题目给出了最高次 k = 1.2.3 时候的自然数幂和求和公式 可以发现求和公式的最高次都是 k+1 那么大胆猜测幂为 k 的自然数幂和肯定可以由一个最高次为 k+1 的多项式表示 不会证明,事实也的确如此 此时就变成了一个拉格朗日插值的模板题了 只要先算出 k+2 个值.然后就能确定最高次为 k+1 的多项式 套模板求值即可 当然自然数幂和不止这一种做法.例如伯努利数.斯特林数等 详细可参考 ==

51nod1228 序列求和(自然数幂和)

与UVA766 Sum of powers类似,见http://www.cnblogs.com/IMGavin/p/5948824.html 由于结果对MOD取模,使用逆元 #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<map> #in

「刷题」JZPKIL

这道反演题,真牛逼. 以下用$B$代表伯努利数,$l*g=f$代表狄利克雷卷积,先推式子. 对于给出的$n,x,y$求一百组数据的$ans$ $\begin{array}{rcl} ans & = & \sum\limits_{i=1}^ngcd(i,n)^xlcm(i,n)^y\end{array}$ $\begin{array}{rcl} & = & \sum\limits_{i=1}^ngcd(i,n)^x\frac{(in)^y}{gcd(i,n)^y}\end{a

[转] POJ数学问题

转自:http://blog.sina.com.cn/s/blog_6635898a0100magq.html 1.burnside定理,polya计数法 这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能完全看懂了,理解了再去做题,不要只记个公式. *简单题:(直接用套公式就可以了) pku2409 Let it Bead      http://acm.pku.edu.cn/JudgeOnline/problem?id=2409 pku2154 Co

『转』数学专辑

1.burnside定理,polya计数法 这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能完全看懂了,理解了再去做题,不要只记个公式. *简单题:(直接用套公式就可以了) pku2409 Let it Bead   http://acm.pku.edu.cn/JudgeOnline/problem?id=2409 pku2154 Color http://acm.pku.edu.cn/JudgeOnline/problem?id=2154 pku12

ACM数学(转)

从放暑假前周sir给我讲了一个用polya计数法和burnside定理做的题目(pku2409)后,突然觉得组合数学挺有意思,然后从那时起到现在几乎都在做这类的题目. 做到现在感觉这类题目的一些基本知识点都差不多有所了解了,水题也刷了不少,但还有很多难题自己实在是做不动,所以准备把这类题目先放一放,然后把前段时间做的水题整理一下(供以后的初学者参考,大牛就不要看了哈,都是水题).剩下的比较难的题目就慢慢来吧,以后做出来再不上,这个小结会不断地更新.也希望大家有好的题目可以推荐一下,分享一下哈.