[luoguP10217/联合省选 2024] 季风
题意
给定 \(n,k,x,y\) 和 \(2n\) 个整数 \(x_0,y_0,x_1,y_1,\dots,x_{n-1},y_{n-1}\)。
找到最小的非负整数 \(m\),使得存在 \(2m\) 个实数 \(x_0',y_0',x_1',y_1',\dots,x_{m-1}',y_{m-1}'\) 满足以下条件,或报告不存在这样的 \(m\):
- \(\sum \limits_{i=0}^{m-1} (x_i'+x_{i \bmod n})=x\);
- \(\sum \limits_{i=0}^{m-1} (y_i'+y_{i \bmod n})=y\);
- \(\forall 0\leq i\leq m-1,|x_i'|+|y_i'|\leq k\)。
特别地,\(m=0\) 时,认为 \(\sum \limits_{i=0}^{m-1} (x_i'+x_{i \bmod n})\) 和 \(\sum \limits_{i=0}^{m-1} (y_i'+y_{i \bmod n})\) 均为 \(0\)。
sol
第三条限制等价于 \(|\sum \limits_{i=0}^{m-1}x_{i \bmod n}|+|\sum \limits_{i=0}^{m-1}y_{i \bmod n}| \le mk\),也就是 \(|x - \sum \limits_{i=0}^{m-1}x_i'|+|y - \sum \limits_{i=0}^{m-1}y_i'| \le mk\)
注意到可以拆分为不同周期:设 \(m=pn+q\),变为 \(|x - p\sum \limits_{i=0}^{n-1}x_i - \sum \limits_{i=0}^{q-1}x_i|+|y - p\sum \limits_{i=0}^{n-1}y_i - \sum \limits_{i=0}^{q-1}y_i| \le mk\),可以枚举每一个 \(q\),解这个绝对值不等式,求出最小的 \(p\) 的正整数解,取最小的 \(pn+q\) 即为答案。
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 100005;
const LL INF = 9e18;
const double eps = 1e-8;
LL sx[N], sy[N];
int n, k, X, Y;
int T;
double l, r;
int dx[] = {1, 1, -1, -1}, dy[] = {1, -1, 1, -1};
void calc_range(double x, double y){
l = max(l, x), r = min(r, y);
}
int main(){
scanf("%d", &T);
for (int cs = 1; cs <= T; cs ++ ) {
scanf("%d%d%d%d", &n, &k, &X, &Y);
for (int i = 1; i <= n; i ++ ) {
scanf("%lld%lld", &sx[i], &sy[i]);
sx[i] += sx[i - 1], sy[i] += sy[i - 1];
}
LL ans = 9e18;
for (int i = 0; i < n; i ++ ) {
l = -INF, r = INF;
for (int j = 0; j < 4; j ++ ){
LL coeff = dx[j] * sx[n] + dy[j] * sy[n] + (LL) n * k;
LL lft = dx[j] * sx[i] + dy[j] * sy[i] + (LL) i * k;
LL div1 = dx[j] * X + dy[j] * Y - lft;
if (coeff == 0) {
if (div1 <= 0) continue;
calc_range(INF, -INF);
break;
}
else if (coeff < 0) calc_range(-INF, 1.0 * div1 / coeff);
else calc_range(ceil(1.0 * div1 / coeff), INF);
}
calc_range(0, INF);
if (l - r > eps) continue;
ans = min(ans, (LL) ceil(l) * n + i);
}
printf("%lld\n", ans >= INF ? -1 : ans);
}
return 0;
}
蒟蒻犯的若至错误
- 计算时直接取整数,导致出现两个非 \(0\) 解时取到不合法解
- eps 过大