两次二分,第一次取得最小值,第二次往右二分看是否能到更右边
注意超出部分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;
}