[数学][YandexAlgorithm2013T4]Infinite Sum

Çàäà÷à D. Innite Sum
Èìÿ âõîäíîãî ôàéëà: standard input
Èìÿ âûõîäíîãî ôàéëà: standard output
Îãðàíè÷åíèå ïî âðåìåíè: 2 se conds
Îãðàíè÷åíèå ïî ïàìÿòè: 256 mebibytes
The statement of this problem i s very short. Calculate the sum
1 P
n=1
n
a
b
n
.
Ôîðìàò âõîäíîãî ôàéëà
The rst li ne of input contains two integersaandb(1a; b10) searated by a single space.
Ôîðìàò âûõîäíîãî ôàéëà
Output the word infinity if the series diverges. Otherwise, output the sum of the series
in form of simplied fraction if the answer is rational, or the word irrational if the answer if
irrational.
Ïðèìåðû
standard inp ut standard output
1 2 2/1

2 1 infinity


上国外神牛的题解。


转载地址:http://codeforces.com/blog/entry/8321


突破口在于构造n+1,然后用二项式定理,最后得到Σn^k/b^n这部分,这样便可以得到递推公式

但是神牛没有写完,最后一步还需要移项,才能求出f(a,b),当然对于神牛们这都可以省略了。抓狂

这个分数类相对于高精度类来说,简单多了。

#include <cstdio>

typedef long long ll;

ll gcd(ll a,ll b)
{
	while (b)
	{
		ll tmp = a % b;
		a = b;
		b = tmp;
	}
	return a;
}

struct frac
{
	private:
		ll zi;
		ll mu;

	public:
		frac(ll a=0,ll b=1):zi(a),mu(b){}
		void operator+=(const frac f2)
		{
			ll fenmu = mu*f2.mu/gcd(mu,f2.mu);
			zi = zi*(fenmu/mu)+f2.zi*(fenmu/f2.mu);
			mu = fenmu;
		}
		void operator/=(const ll b)
		{
			mu *= b;
			ll tmp = gcd(zi,mu);
			zi /= tmp;
			mu /= tmp;
		}
		friend frac operator*(const ll a,const frac& b)
		{
			frac f2;
			f2.zi = b.zi*a;
			f2.mu = b.mu;
			ll tmp = gcd(f2.zi,f2.mu);
			f2.zi /= tmp;
			f2.mu /= tmp;
			return f2;
		}
		void output()
		{
			printf("%I64d/%I64d",zi,mu);
		}
};


bool calc[20][20];
frac F[20][20];
ll c[20][20];

frac f(ll a,ll b)
{
	if (calc[a][b])
		return F[a][b];
	F[a][b] = frac(1,1);
	for (ll k=0;k<a;k++)
		F[a][b] += c[a][k]*f(k,b);
	F[a][b] /= (b-1);
	calc[a][b] = true;
	return F[a][b];
}

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

	int a,b;
	scanf("%d%d",&a,&b);
	if (b == 1)
	{
		printf("infinity");
		return 0;
	}

	for (int i=1;i<=10;i++)
	{
		c[i][0] = c[i][i] = 1;
		for (int j=1;j<i;j++)
		{
			c[i][j] = c[i-1][j-1]+c[i-1][j];
		}
	}


	f(a,b).output();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值