2021牛客多校3 E/nowcoder 11254 E Math

题目链接:https://ac.nowcoder.com/acm/contest/11254/E

题目大意:\(\sum_{i=1}^{n}\sum_{j=1}^{j\leqslant i} \left [ ij+1\mid i^{2} + j^{2}\right ]\)

题目思路:
\(xy+1\mid x^{2} + y^{2}\)即为\(x^{2} + y^{2} = k\left ( xy+1 \right )\)将x看为常数,得\(y^{2}-kxy+x^{2}-k=0\),根据韦达定理:

\[\left\{\begin{matrix} y_{1}+y_{2} = -\frac{a}{b} = kx\\ y_{1}y_{2}=\frac{a}{c} = x^{2}-k \end{matrix}\right. \]

若有一组\(\left ( x,y \right )\)满足条件,则\(\left ( x,kx-y \right )\)也满足条件,设\(y\geqslant x\),容易得到\(kx-y \leqslant y\)。我们可以通过递降推出其他解,即构造\(\left ( x',y' \right )\),使\(x' = kx - y\)\(y' = x\),此时仍然满足\(x^{2} + y^{2} = k\left ( xy+1 \right )\),继续将\(x'\)看成常数向下递降,即\((x,y)\rightarrow (kx-y,x)\)

之前我直接构造\(\left ( x',y' \right )\),使\(x' = x,y' = kx - y\),然后我发现继递降出来的是\(kx - y' = y\),这不和没构造一样吗 (bushi

而且这样递降下来的\(y'\geqslant 0\),若将\(y'< 0\)代入\(x^{2} + y^{2} = k\left ( xy+1 \right )\),得到正数=负数,显然\(y'\geqslant 0\),将\(y = 0\)代入得\(k=x^{2}\),通过往回递增得

\[\left\{\begin{matrix} x' = kx - y\\ y' = x \end{matrix}\right. \rightarrow \left\{\begin{matrix} x = y'\\ y = ky' - x' \end{matrix}\right. \]

\((x',y')\rightarrow (y',x^{2}y'- x') = (x,y)\)
\((x,x^{3})\rightarrow (x^{3},x^{5}-x)\rightarrow (x^{5}-x,x^{7}-2x^{3})\rightarrow ……\)
然后枚举x,二分查找即可
水群时看见这个好像叫韦达跳跃
想了解的更多可以看看OEIS关于这个定理的解释

AC代码:

#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <stack>
#include <deque>
#include <queue>
#include <cmath>
#include <map>
#include <set>
using namespace std;
typedef __int128 int128;
typedef pair<int, int> PII;
typedef pair<double, int> PDI;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10, M = 1e6 + 30;
const int base = 1e9;
const int P = 131;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1.0);
int a[N];
vector<int128> vec;
void inif()
{
	vec.push_back(1);
	for (int128 k = 2; k <= 1e6; ++k)
	{
		int128 a = k, b = k * k * k, c;
		while (1)
		{
			if (b > 1e18)
				break;
			vec.push_back(b);
			c = k * k * b - a;
			a = b, b = c;
		}
	}
	sort(vec.begin(), vec.end());
}
int main()
{
	inif();
	int T;
	scanf("%d", &T);
	while (T--)
	{
		ll x;
		scanf("%lld", &x);
		int128 n = x;
		int p = lower_bound(vec.begin(), vec.end(), n) - vec.begin();
		if (vec[p] > n)
			--p;
		printf("%d\n", p + 1);
	}
	return 0;
}
posted @ 2021-07-26 08:42  xiaopangpang7  阅读(103)  评论(0编辑  收藏  举报