题意:
两个人分一块横坐标0~R,纵坐标无限大的土地,里面有许多矩形形状的绿洲,保证绿洲没有重叠
需要选定一个整数横坐标x,满足:
1.坐标左侧的绿洲面积大于等于右侧的绿洲面积
2.坐标左侧的面积要尽可能大
问x是多少
思路:
要满足第二个条件,只需要从R处向左找第一个满足条件的位置,问题在如何快速求出左右两侧的绿洲面积
绿洲都是矩形,假设有一个左上角坐标XY,宽度W高度H的矩形,我们可以将它看作区间[X,X+W]上值加H
然后利用差分数组,在X位置加H,在X+W+1位置减H,然后求一下前n项和就是1~i处的绿洲面积,最后遍历查找就可以了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 100010
#define mod 1000000007
#define inf 0x3f3f3f3f
int r,n;
ll num[1000100];
int main(int argc, char const *argv[]) {
int t;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof num);
scanf("%d%d",&r,&n);
for(int i=1;i<=n;i++)
{
int x,y,w,h;
scanf("%d%d%d%d",&x,&y,&w,&h);
num[x]+=h;
num[x+w]-=h;
}
ll sum=0;
for(int i=1;i<=r;i++)
{
sum+=num[i];
num[i]=sum+num[i-1];
}
int ans=-1;
ll minn=10000000010;
for(int i=r;i>=1;i--)
{
ll k1=num[i-1];
ll k2=num[r]-num[i-1];
if((k1>=k2)&&(k1-k2<minn))
{
minn=k1-k2;
ans=i;
}
}
printf("%d\n",ans);
}
return 0;
}