2021牛客多校3 E

16 篇文章 0 订阅
6 篇文章 0 订阅

题目大意:

t ( ≤ 1 e 5 ) t(\le 1e5) t(1e5)次询问,每次询问给定 n ( ≤ 1 e 18 ) n(\le 1e18) n(1e18),给出有多少组 ( x , y ) (x,y) (x,y)满足 ( x y + 1 ) ∣ ( x 2 + y 2 ) (xy+1)|(x^2+y^2) (xy+1)(x2+y2)

解题思路:

  • ( x 2 + y 2 ) = k ( x y + 1 ) (x^2 + y^2)=k(xy+1) (x2+y2)=k(xy+1)
  • 固定x不懂,由韦达定理,存在另一个 y ′ y' y满足 y + y ′ = k x , y y ′ = x 2 − k y+y'=kx,yy'=x^2-k y+y=kxyy=x2k 不妨设 x ≤ y x\le y xy
  • ( x , y ′ ) (x,y') (x,y)也是一组解,并且 y ′ ≥ 0 , y ′ ≤ y y' \ge 0, y' \le y y0,yy
  • 因为方程 x x x y y y是对称的,所以可以设小的 y ′ y' y为对称轴,得到更小的 x ′ x' x和其对应,大概就类似如下图递降下去直到 y ′ = 0 y'=0 y=0
    在这里插入图片描述
  • 最后要求 y = k x , k = x 2 y=kx,k=x^2 y=kx,k=x2
  • 然后根据这个解再逆推出所有解
  • ( x , y ′ ) → ( k x − y ′ , x ) → . . . (x,y')\rightarrow (kx-y',x) \rightarrow... (x,y)(kxy,x)...

AC代码:

#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) //不能跟puts混用
#define seteps(N) fixed << setprecision(N)
#define endl "\n"
const int maxn = 1e6 + 10;
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
const ll mod = 1e9 + 7;
const ll M = 1e18;
vector <ll> ans;
// __int128 x;
int main() {
	for (ll k = 2; k * k * k <= M; k++) { //k从2开始,所以最后答案要考虑+1,因为k=1没有考虑
		ll now = k * k * k, pre = k;
		ll t;
		__int128 tmp = k * k;
		while (1) {
			ans.pb(now);
			if (tmp * now - pre > M) break;
			t = now;
			now = tmp * now - pre;
			pre = t;
		}
	}
	sort (ans.begin(), ans.end());
	int t;
	ll n;
	cin >> t;
	while (t--) {
		cin >> n;
		cout << upper_bound(ans.begin(), ans.end(), n) - ans.begin() + 1 << endl;
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值