二分 hihoCoder1249 Xiongnu's Land
  NUnxBARy5ERY 2023年11月02日 39 0


传送门:​​点击打开链接​

题意:沙漠中有许多块矩形水源,水源不相交,问能否找到一根中轴线,使得轴线左边的水源面积大于等于右边的水源面积。在满足两个面积之差最小的情况下,使得轴线靠近右端点

思路:只能说当时现场赛的时候太脑残了,。要分两次二分!一次二分是做不到的。第一次二分求出左边面积大于等于右边面积时,使两边之差最小,那么此时左边面积等于多少

第二次二分再去让左边面积等于这么多,然后更加靠近右边的位置是哪里。

那么这样下来,就能求出答案了- -

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;

const int MX = 10000 + 5;
struct Seg {
int l, r, h;
} S[MX];

LL sum;
int n, Rig;

LL get(int x) {
LL ret = 0;
for(int i = 1; i <= n; i++) {
if(S[i].l < x) {
ret += (LL)(min(S[i].r, x) - S[i].l) * S[i].h;
}
}
return ret;
}

int solve() {
int l = 0, r = Rig, m;
while(l <= r) {
m = (l + r) >> 1;
LL left = get(m);
if(left >= sum - left) r = m - 1;
else l = m + 1;
}

LL ans = get(r + 1);

l = 0, r = Rig;
while(l <= r) {
m = (l + r) >> 1;
LL left = get(m);
if(left > ans) r = m - 1;
else l = m + 1;
}
return l - 1;
}

int main() {
int T; //FIN;
scanf("%d", &T);
while(T--) {
sum = 0;
scanf("%d%d", &Rig, &n);
for(int i = 1; i <= n; i++) {
scanf("%d%*d%d%d", &S[i].l, &S[i].r, &S[i].h);
S[i].r += S[i].l;
sum += (LL)(S[i].r - S[i].l) * S[i].h;
}
printf("%d\n", solve());
}
return 0;
}



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  JBfJ5LpBD0AJ   2023年11月13日   23   0   0 初始化链表#define
  HE3leaVn7jMN   2023年11月24日   28   0   0 Timei++#include
  HE3leaVn7jMN   2023年11月26日   28   0   0 i++#include
NUnxBARy5ERY
作者其他文章 更多