2020.9.13 NOIP模拟赛4 T2 math

题目描述:已知 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(p1)+a2f(p2)+a3f(p3)
这样才对得起他给出的三个式子

然后就是配式子
或者说直接设 f ( p ) = ( a + b + c ) ∗ f ( p − 1 ) − . . . f(p)=(a+b+c)*f(p-1)-... f(p)=(a+b+c)f(p1)...也可以求解
这就需要数学的基础和灵感了
最后解得: 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值