2025.1.1 闲话

机智地把题目改为了 2025!

凸性定义:

  • 对于凸集 \(C\)\(f:C\to\R\) 是凸函数当且仅当 \(\forall p,q\in C,\forall\lambda\in[0,1],f(\lambda p+(1-\lambda)q)\le\lambda f(p)+(1-\lambda)f(q)\) .
  • 对于凸集 \(C\)\(f:C\to\R\) 是凹函数当且仅当 \(\forall p,q\in C,\forall\lambda\in[0,1],f(\lambda p+(1-\lambda)q)\ge\lambda f(p)+(1-\lambda)f(q)\) .

wqs 二分通常解决这样一类问题:\(f\) 是凹函数,要求 \(f(x)\),但是只能求 \(\max\limits_x\{f(x)-kx\}\) .

缺点:

  • 常规 wqs 二分面临着一系列共线的边界情况 .
  • 实数二分精度玄学,如果求 \(\max\limits_x\{f(x)-kx\}\) 的过程中精度损失过大可能会爆炸 .
  • 无法扩展到高维 .
  • (它最坏了)

介绍:严格 wqs 二分!

根据拉格朗日对偶的相关理论:对于凹函数 \(f\)\(g(k)=\max\limits_x\{f(x)-kx\}+ka\) 是凸函数且最小值为 \(f(a)\) .

那么只需要二分求单峰函数最小值就可以了,由于只需要比较函数值所以没有共线的问题 .

整数二分的例子:

inline int wqs(auto&& f, int k) // f: function<int(int)>
{
	int l = -1e9, r = 1e9;
	auto g = [&](int x){return f(x) + x * k;};
	while (l < r)
	{
		int mid = (l + r) >> 1, f1 = g(mid), f2 = g(mid + 1);
		if (f1 == f2) return f1;
		if (f1 > f2) l = mid + 1;
		else r = mid;
	}
	return g(l);
}

那么可以方便地解决一些高维 wqs 二分问题:

CF1799F Halve or Subtract

给一个长度为 \(n\) 的序列 \(\{a\}\) 和正整数 \(b\),可以每次选一个 \(i\),总共做 \(k_1\)\(a_i\gets\lceil\frac{a_i}2\rceil\),总共做 \(k_2\)\(a_i\gets\max\{a_i-b,0\}\),一个位置同一种操作只能做至多一次 .

问操作之后 \(\sum a_i\) 的最小值 .

显然先除再减更优,又因为只做除或减有显然的费用流模型,所以答案 \(f(k_1,k_2)\) 对于 \(k_1,k_2\) 都是凸的 .

那么使用 2d wqs 二分即可!时间复杂度 \(O(n\log^2V)\) .

代码

感恩 std::function 和 lambda 表达式!

const int N = 5555;
int n, b, k1, k2, a[N];
inline ll calc(int x, int y)
{
	ll ans = 0;
	for (int i=1; i<=n; i++) ans += min(min(a[i], (a[i] + 1) / 2 - x), min(max(a[i] - b, 0) - y, max((a[i] + 1) / 2 - b, 0) - x - y));
	return ans;
}
inline ll wqs(auto&& f, int k)
{
	int l = -1e9, r = 0;
	auto g = [&](int x){return f(x) + 1ll * x * k;};
	while (l < r)
	{
		int mid = (l + r) >> 1;
		ll f1 = g(mid), f2 = g(mid + 1);
		if (f1 == f2) return f1;
		if (f1 < f2) l = mid + 1;
		else r = mid;
	}
	return g(l);
}
int main()
{
	int T; scanf("%d", &T);
	while (T--)
	{
		scanf("%d%d%d%d", &n, &b, &k1, &k2);
		for (int i=1; i<=n; i++) scanf("%d", a+i);
		printf("%lld\n", wqs([&](int x){return wqs([&](int y){return calc(y, x);}, k1);}, k2));
	}
	return 0;
}

严格 wqs 二分,快乐的二分!

Ref. 严谨的 WQS 二分方法 .

歌:ラブリージャッジメント - いるかアイス feat. ちょこ(怒槌.jpg).

posted @ 2025-01-01 16:38  yspm  阅读(132)  评论(2编辑  收藏  举报
😅​