【题解】CF1687D-Cute number
一道很有意思的小清新题。
首先我们知道两个相邻平方数 \(p^2,(p+1)^2\) 之间距离 \(2x+1\) 一定是奇数,所以 cute 数的范围一定是 \([p^2,p^2 + p]\)。
直接做没有头绪,考虑用枚举降低难度。我们试着枚举 \(p^2\le a_1 + k \le p ^2 + p\),所以 \(k\) 的取值为 \([p^2 - a_1, p^2 + p - a_1]\)。
接下来我们看 \(a_2\),那么如果 \(a_2\) 的 \(p\) 不变,\(k\) 的区间就是 \([p^2 - a_2,p^2 + p - a_2]\),由于 \(a_2 \ge a_1\),所以条件只有一个就是 \(p^2 + p- a_2 \ge p^2 - a_1\)。如果 \(p\) 增大了,那么有 \((p + c) ^2 - (p^2 + p) \ge p + 1\),所以 \(p\) 不变和 \(p\) 增大中,最多只有一个符合条件,所以我们不用进行决策。
同时观察到如果 \(p\) 增大需要满足 \((p+c) ^ 2 - a_2 \le p^2 + p - a_1 \to a_2 - a_1\ge p + 1\),所以枚举 \(p\) 后,\(p\) 最多增大 \(\dfrac{a_n}{p + 1}\) 次。所以直接暴力做的时间复杂度是 \(\mathcal{O}(a_n\ln a_n)\),不需要用到任何算法或数据结构。
#define N 2000005
int n, a[N], b[N], c[N];
inline int calc(int x){return sqrt(x) + eps;}
signed main() {
read(n);
rp(i, n)read(a[i]);
n = unique(a + 1, a + n + 1) - a - 1;
rp(i, n)c[a[i]] = b[a[i]] = a[i];
rp(i, a[n])if(!b[i])b[i] = b[i - 1];
pr(i, a[n])if(!c[i])c[i] = c[i + 1];
rp(p, a[n]){
int x = (a[1] + p <= a[n] ? c[a[1] + p + 1] : 0), y = (a[1] + p >= a[n] ? a[n] : b[a[1] + p]),
l = max(0LL, p * p - a[1]), r = p * (p + 1) - y;
while(x){
int q = calc(x + l), y = x + p >= a[n] ? a[n] : b[x + p];
if(q * (q + 1) - x < l)q++;
cmx(l, q * q - x), cmn(r, q * (q + 1) - y);
if(l > r || x + p >= a[n])break;
x = c[x + p + 1];
}
if(l <= r){printf("%lld\n", l); return 0;}
}
return 0;
}