Utawarerumono(裴蜀定理)

  • 注释:本章涉及的数为整数
  • 题面
  • 题意:见题面。
  • 解决思路:首先判断 a x + b y = c \small ax+by=c ax+by=c是否有解,由裴蜀定理可知, ( a , b ) ∣ c \small (a,b)\mid c (a,b)c时有解。
    此时计算 p 2 x 2 + p 1 x + q 2 y 2 + q 1 y \small p_2x^2+p_1x+q_2y^2+q_1y p2x2+p1x+q2y2+q1y最小值,发现有两个未知数,不好判断,所以将 a x + b y = c \small ax+by=c ax+by=c转换为 y = c − a x b \small y=\large \frac{c-ax}{b} y=bcax代入方程。
    ∴ f ( x ) = p 2 x 2 + p 1 x + q 2 ( c 2 + a 2 x 2 − 2 a c x ) b 2 + q 1 ( c − a x ) b \small\therefore f(x)=p_2x^2+p_1x+\large\frac{q_2(c^2+a^2x^2-2acx)}{b^2}\small+\large\frac{q_1(c-ax)}{b} f(x)=p2x2+p1x+b2q2(c2+a2x22acx)+bq1(cax)
    ∴ f ( x ) = ( p 2 + a 2 q 2 b 2 ) x 2 + ( p 1 − 2 a c q 2 b 2 − a q 1 b ) x + q 2 c 2 b 2 + q 1 c b \small\therefore f(x)=(p_2+\large\frac{a^2q_2}{b^2}\small)x^2+(p_1-\large\frac{2acq_2}{b^2}\small - \large\frac{aq_1}{b}\small)x+\large\frac{q_2c^2}{b^2}\small+\large\frac{q_1c}{b} f(x)=(p2+b2a2q2)x2+(p1b22acq2baq1)x+b2q2c2+bq1c
    由抛物线性质可知:方程 f ( x ) \small f(x) f(x)的最小值在对称轴处
    x = q 1 a b + 2 a c q 2 b 2 − p 1 2 ( p 2 + a 2 q 2 b 2 ) \small x=\large\frac{\large\frac{q_1a}{b}\small+\large\frac{2acq_2}{b^2}\small-p_1}{2(p_2+\large\frac{a^2q_2}{b^2}\small)} x=2(p2+b2a2q2)bq1a+b22acq2p1
    上下同时乘 b 2 \small b^2 b2
    x = a b q 1 + 2 a c q 2 − b 2 p 1 2 b 2 p 2 + 2 a 2 q 2 \small x=\large\frac{abq_1+2acq_2-b^2p_1}{2b^2p_2+2a^2q_2} x=2b2p2+2a2q2abq1+2acq2b2p1
    所以直接计算找出小于对称轴且满足 a x + b y = c \small ax+by=c ax+by=c与大于对称轴且满足 a x + b y = c \small ax+by=c ax+by=c的方程值,取最小即可。
    满足方程的判断:因为 x \small x x已知且是整数,所以对于方程 a x + b y = c \small ax+by=c ax+by=c直接判断 y \small y y是否为整数就行,所以判断 y = c − a x b \small y=\large \frac{c-ax}{b} y=bcax为整数即可,即当 b ∣ ( c − a x ) \small b\mid (c-ax) b(cax) y \small y y为整数, a x + b y = c \small ax+by=c ax+by=c有解
  • AC代码
//优化
#pragma GCC optimize(2)
//C
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//C++
#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<istream>
#include<iomanip>
#include<climits>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
//宏定义
#define N 1010
#define DoIdo main
//#define scanf scanf_s
#define it set<ll>::iterator
#define TT template<class T>
//定义+命名空间
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 19260817;
const ll INF = 1e18;
const int maxn = 1e6 + 10;
using namespace std;
//全局变量
//函数区
ll max(ll a, ll b) {
    
     return a > b ? a : b; }
ll min(ll a, ll b) {
    
     return a < b ? a : b; }
ll gcd(ll a, ll b) {
    
     return !b ? a : gcd(b, a % b); }
//主函数
int DoIdo() {
    
    

	ios::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);

	ll a, b, c;
	ll p1, p2, q1, q2;

	cin >> a >> b >> c;
	cin >> p1 >> p2;
	cin >> q1 >> q2;

	ll g = gcd(a, b);
	if (c % g) {
    
    
		cout << "Kuon" << endl;
	}
	else {
    
    
		ll mid = (a * b * q1 + 2 * a * c * q2 - p1 * b * b) / (2 * b * b * p2 + 2 * a * a * q2);
		ll x1 = mid, x2 = mid;
		while ((c - a * x1) % b) x1--;
		while ((c - a * x2) % b) x2++;

		ll y1 = (c - a * x1) / b;
		ll y2 = (c - a * x2) / b;

		ll ans1 = p2 * x1 * x1 + p1 * x1 + q2 * y1 * y1 + q1 * y1;
		ll ans2 = p2 * x2 * x2 + p1 * x2 + q2 * y2 * y2 + q1 * y2;
		cout << min(ans1, ans2) << endl;
	}
	return 0;
}
//分割线---------------------------------QWQ
/*



*/

猜你喜欢

转载自blog.csdn.net/qq_45739057/article/details/106309482