(1)题目大意
一个人想提升下棋的rating,但是他只能一轮一轮来,若是他大于或者等于对战的那个人的rating,他的rating就会加1,那个对战的人rating不变,若是他的rating小于对战的那个人的rating,他的rating就会减1,问你他的rating能否有可能从x变成y,如果有输出最小对战次数,否则输出0.
(2)解题思路
考虑二分答案,二分k轮,对于k轮我们算一下可以产生多少rating,以及下一轮最大可以有多少rating,我们从小到大去打对手,若是不敌,我们考虑能否在k轮内使得能打过,然后下一次 每轮最大获得rating可以增加2了,最后给每一个ans取个min即可。
(3)代码实现
// Problem: G. Gaining Rating
// Contest: Codeforces - Codeforces Round #839 (Div. 3)
// URL: https://codeforces.com/contest/1772/problem/G
#include "bits/stdc++.h"
#define rep(i, z, n) for (int i = z; i <= n; i++)
#define per(i, n, z) for (int i = n; i >= z; i--)
#define ll long long
#define PLL pair<long long, long long>
#define db double
#define PII pair<int, int>
#define fi first
#define se second
#define vi vector<int>
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
using namespace std;
const int N = 2e5 + 10;
ll a[N];
ll n, now, fur, mius;
PLL check(ll k)
{
//打k轮能获得多少rating
ll tmp = now, minnus = mius;
vector<ll> need;
ll tmpk = k, pt = 0;
rep(i, 1, n)
{
if (tmp >= a[i])
{
tmp += 1;
pt++;
need.push_back(0);
}
else
{
ll cnt = (a[i] - tmp + minnus - 1) / minnus;
if (cnt > tmpk)
{
continue;
}
tmp += cnt * minnus + 1;
pt++;
minnus += 2;
tmpk -= cnt;
need.push_back(cnt);
int j = i + 1;
while (j <= n && a[j] <= tmp)
{
pt++;
tmp++;
need.push_back(0);
minnus += 2;
j++;
}
i = j - 1;
}
}
ll have = 0, pre = 0, cnt = 0;
for (auto x : need)
{
pre += x;
have += (k - (pre)) - (pre);
cnt++;
}
have -= 1LL * (n - cnt) * k;
return {have, pt};
}
void solve()
{
cin >> n >> now >> fur;
rep(i, 1, n)
{
cin >> a[i];
}
sort(a + 1, a + 1 + n);
mius = 0;
ll tmp = now, mx = 0;
rep(i, 1, n)
{
if (tmp >= a[i])
{
tmp++;
mius++;
}
else
{
tmp--;
mius--;
}
if (tmp == fur)
{
cout << i << endl;
return;
}
mx = max(mx, mius);
}
if (mius <= 0)
{
cout << -1 << endl;
return;
}
//每大场净胜minus点rating,mx单场最多拿多少rating
ll dis = fur - now, l = 1, r = 1e12, ans = 1e18;
while (l <= r)
{
ll mid = (l + r) >> 1;
PLL nw = check(mid);
// cout << mid << ',' << nw.fi << ',' << nw.se << endl;
if (nw.fi + nw.se >= dis)
{
r = mid - 1;
ans = min(ans, max(0LL, dis - nw.fi) + mid * n);
}
else
{
l = mid + 1;
}
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while (T--)
solve();
return 0;
}