Çàäà÷à 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
Èìÿ âõîäíîãî ôàéëà: 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;
}