【题解】P8814 题解

P8814 题解

思路分析

这道题首先要知道和积原理

然后,我们开始推式子。

ei×di=(pi1)(qi1)+1=pi×qipiqi+1+1=ni(pi+qi)+2\begin{aligned}e_i \times d_i & = (p_i-1)(q_i-1)+1 \\ & = p_i \times q_i-p_i-q_i + 1+1 \\ & = n_i - (p_i+q_i) + 2\end{aligned}

移项可得 pi+qi=niei×di+2p_i + q_i = n_i - e_i \times d_i + 2,即 pi+qip_i + q_i 一定。根据和积原理,pi+qip_i+q_i 满足单调性。即可以使用二分查找枚举 pip_i 进行计算。

注意:因为要求 piqip_i \leq q_i ,所以将 pip_i 枚举到 pi+qi2\left\lfloor\\\dfrac{p_i+q_i}{2}\right\rfloor 即可。

代码

#include <iostream>
#include <cmath>
#define ll long long
using namespace std;

ll ef(ll l, ll r, ll n, ll m) //二分 
{
	while(l <= r)
	{
		ll mid = ((l + r) >> 1);
		ll cj = mid * (m - mid);//乘积
		if(cj == n)
		{
			return mid;
		}
		else
		{
			if(cj < n)//小于往大的枚举
			{
				l = mid + 1;
			}
			else // 大于往小的枚举
			{
				r = mid - 1;
			}
		}
	}
	return -1;//无解
}

int main()
{
	ll k;
	cin >> k;
	while(k--)
	{
		ll n, e, d;
		cin >> n >> e >> d;
		ll m = n - e * d + 2;//p+q的和
		ll q = ceil(m / 2);//p的枚举上限
		ll x = ef(1ll, q, n, m);
		if(x != -1) cout << x << " " << m - x << endl;
		else cout << "NO" << endl;
	}
	return 0;
}
posted @ 2022-11-14 17:44  邻补角-SSA  阅读(13)  评论(0)    收藏  举报  来源