题目描述:已知
a
+
b
+
c
=
n
,
a
2
+
b
2
+
c
2
=
m
,
a
3
+
b
3
+
c
3
=
k
a+b+c=n, \ a^2+b^2+c^2=m,a^3+b^3+c^3=k
a+b+c=n, a2+b2+c2=m,a3+b3+c3=k
求:
a
p
+
b
p
+
c
p
a^p+b^p+c^p
ap+bp+cp
输入格式:四个整数
n
,
m
,
k
,
p
n,m,k,p
n,m,k,p如题目描述
输出格式:一个整数,即
a
p
+
b
p
+
c
p
a^p+b^p+c^p
ap+bp+cp
数据范围:
0
<
=
n
,
m
,
k
<
=
20
0<=n,m,k<=20
0<=n,m,k<=20
---------------
0
<
=
p
<
=
10
0<=p<=10
0<=p<=10
这一眼就是数学题。
因为是要求
a
p
+
b
p
+
c
p
a^p+b^p+c^p
ap+bp+cp,发现直接解出
a
,
b
,
c
a,b,c
a,b,c不太现实,考虑公式转化,直接让所求答案与上述三个式子直接建立联系看起来也不太现实,那这道题目应该是想让我们递推。
令
f
(
p
)
=
a
p
+
b
p
+
c
p
f(p)=a^p+b^p+c^p
f(p)=ap+bp+cp
因为一共给出了三个式子,理论上
f
(
p
)
=
a
1
f
(
p
−
1
)
+
a
2
f
(
p
−
2
)
+
a
3
f
(
p
−
3
)
f(p)=a_1f(p-1)+a_2f(p-2)+a_3f(p-3)
f(p)=a1f(p−1)+a2f(p−2)+a3f(p−3)
这样才对得起他给出的三个式子
然后就是配式子
或者说直接设
f
(
p
)
=
(
a
+
b
+
c
)
∗
f
(
p
−
1
)
−
.
.
.
f(p)=(a+b+c)*f(p-1)-...
f(p)=(a+b+c)∗f(p−1)−...也可以求解
这就需要数学的基础和灵感了
最后解得:
a
1
=
a
+
b
+
c
a_1=a+b+c
a1=a+b+c
---------------
a
2
=
−
(
a
b
+
b
c
+
a
c
)
a_2=-(ab+bc+ac)
a2=−(ab+bc+ac)
---------------
a
3
=
a
b
c
a_3=abc
a3=abc
有点像
(
a
+
b
+
c
)
3
(a+b+c)^3
(a+b+c)3的展开
接着就是求
a
b
+
b
c
+
a
c
ab+bc+ac
ab+bc+ac
可以得到:
(
a
+
b
+
c
)
2
−
(
a
2
+
b
2
+
c
2
)
=
2
(
a
b
+
b
c
+
a
c
)
(a+b+c)^2-(a^2+b^2+c^2)=2(ab+bc+ac)
(a+b+c)2−(a2+b2+c2)=2(ab+bc+ac)
至于
a
b
c
abc
abc
(
a
+
b
+
c
)
(
a
2
+
b
2
+
c
2
)
=
a
3
+
b
3
+
c
3
+
a
b
(
a
+
b
)
+
b
c
(
b
+
c
)
+
a
c
(
a
+
c
)
=
a
3
+
b
3
+
c
3
+
(
a
b
+
b
c
+
a
c
)
(
a
+
b
+
c
)
−
3
a
b
c
(a+b+c)(a^2+b^2+c^2)=a^3+b^3+c^3+ab(a+b)+bc(b+c)+ac(a+c)=a^3+b^3+c^3+(ab+bc+ac)(a+b+c)-3abc
(a+b+c)(a2+b2+c2)=a3+b3+c3+ab(a+b)+bc(b+c)+ac(a+c)=a3+b3+c3+(ab+bc+ac)(a+b+c)−3abc
(其实知道这个式子会有很大帮助)
根据前面的推论就可以求出
a
b
c
abc
abc
最后递推即可
(其实本质就是插项、拼凑、递推、展开)
考场上想不出来阿
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 30;
struct w{
int x, y;
inline w(int xx = 0){x = xx, y = 1;}
}f[MAXN + 10];
int gcd(int a, int b){return b? gcd(b, a % b) : a;}
inline w operator + (const w &x, const w &y){
int d = gcd(x.y, y.y); w ans;
ans.y = x.y * y.y / d;
ans.x = x.x * y.y / d + y.x * x.y / d;
d = gcd(ans.x, ans.y);
ans.x /= d, ans.y /= d;
return ans;
}
inline w operator - (const w &x, const w &y){
w z = y; z.x = -z.x;
return x + z;
}
inline w operator * (const w &x, const w &y){
int d1 = gcd(x.x, y.y), d2 = gcd(x.y, y.x); w ans;
ans.x = x.x / d1 * y.x / d2;
ans.y = x.y * y.y / d1 / d2;
return ans;
}
inline w operator / (const w &x, const w &y){
w z = y; swap(z.x, z.y);
return x * z;
}
signed main(){
freopen ("math.in","r",stdin);
freopen ("math.out","w",stdout);
w n, m, k, p, s, t;
w ans;
scanf("%lld%lld%lld%lld", &n.x, &m.x, &k.x, &p.x);
s = (n * n - m) / w(2);
t = (k + (s * n) - n * m) / w(3);
f[1] = n, f[2] = m, f[3] = k;
for (register int i = 4; i <= p.x; ++i)
f[i] = n * f[i - 1] - s * f[i - 2] + t * f[i - 3];
printf("%lld/%lld\n", f[p.x].x, f[p.x].y);
return 0;
}