15北京区域赛——A 二分——hihoCoder 1249 Xiongnu's Land
两次二分,第一次取得最小值,第二次往右二分看是否能到更右边
注意超出部分land部分要去掉
#include <cstdio> #include <algorithm> using namespace std; typedef long long ll; struct edge{ int x, y, w, h; }a[10010]; bool cmp(edge A, edge B) { return A.x < B.x; } int n; ll cal(int x) { ll S = 0; for(int i = 1; i <= n; i++){ if(a[i].x < x){ S += 1ll * (min(x, a[i].x + a[i].w) - a[i].x) * min(a[i].h, a[i].y); } } return S; } int main() { int T, R; scanf("%d", &T); while(T--){ int l, r, mid; scanf("%d", &R); scanf("%d", &n); ll Sum = 0; // max_r = R; for(int i = 1; i <= n; i++){ scanf("%d%d%d%d", &a[i].x, &a[i].y, &a[i].w, &a[i].h); Sum += 1ll * min(a[i].h, a[i].y) * min(a[i].w, R - a[i].x); } sort(a + 1, a + n + 1, cmp); l = 0; r = R; ll S, _S; ll f_S = 1e13; int ans = R; while(l <= r){ mid = l + r >> 1 ; S = cal(mid); _S = S - (Sum - S); // printf("%d %lld\n", mid, _S); if(_S >= 0){ if( _S <= f_S){ //printf("%d %d ", l, r); r = mid - 1; f_S = _S; ans = min(ans, mid); // printf("%d\n", ans); } else l = mid + 1; } else l = mid + 1; } r = R; l = ans; while(l <= r){ mid = l + r >> 1; S = cal(mid); _S = S - (Sum - S); if(_S < f_S) l = mid + 1; if(_S == f_S){ ans = max(ans, mid); l = mid + 1; } else r = mid - 1; } printf("%d\n", ans); } return 0; }