玄学二分求解答
查看原帖
玄学二分求解答
1439183
Burning_Red楼主2025/7/31 17:40

我的第一个二分采用了这样的写法, Ton#3#4 80pts:

ll l = -3e8, r = 3e8, mid;
	while (l < r) {
		mid = (l + r) / 2;
		if (check(mid)) {
			l = mid + 1;
		} else {
			r = mid;
		}
	}
	cout << r - 1;

第二个AC了,仅仅是换了这种写法:

ll l = -3e8, r = 3e8, mid;
while (l <= r) {
		mid = (l + r) / 2;
		if (check(mid)) {
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	cout << r;

更玄学的是,我看了一份题解采用了这种写法可以AC,而我换上之后竟然Ton#7#9 80pts

ll l = -3e8, r = 3e8, mid;
	ll l = -3e8, r = 3e8, mid;
	while (l < r) {
		mid = (l + r) / 2;
		if (check(mid)) {
			l = mid;
		} else {
			r = mid - 1;
		}
	}
	cout << r;

蒟蒻求解答,下面是AC代码可以看看问题在哪

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const ll N = 1e5 + 10;

struct node{
	ll x, y;
	bool operator<(const node &a) {
		if(x == a.x) return y < a.y; 
		return x < a.x; 
	}
} A[N], T[N];

ll n, k;

ll lowbit(ll x) {
	return x & -x;
}

ll tree[N];

void update(ll x, ll d) {
	while (x <= n) {
		tree[x] += d;
		x += lowbit(x);
	}
}

ll query(ll x) {
	ll sum = 0;
	while (x > 0) {
		sum += tree[x];
		x -= lowbit(x);
	}
	return sum;
}

bool check(ll x) {
	ll sum = 0, t = 0;
	for (int i = 1; i <= n; i++) {
		if (A[i].x == A[t].x) {
			sum -= (i - t);
		} else {
			t = i;
		}
		T[i].x = A[i].y - x * A[i].x;
		T[i].y = i;
	}
	sort(T + 1, T + 1 + n);
	for (int i = 1; i <= n; i++) {
		sum += query(T[i].y);
		update(T[i].y, 1);
	}
	for (int i = 1; i <= n; i++) {
		tree[i] = 0;
	}
	if (sum >= k) {
		return 1;
	} else {
		return 0;
	}
}

int main() {
	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		scanf("%lld%lld", &A[i].x, &A[i].y);
	}
	sort(A + 1, A + 1 + n);
	ll l = -3e8, r = 3e8, mid;
	while (l <= r) {
		mid = (l + r) / 2;
		if (check(mid)) {
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	cout << r;
	return 0;
}
2025/7/31 17:40
加载中...