agc034C Tests

题意:$n$场考试,满分$X$分。你的对手每场考试得了$b_i$分。你每学习一个小时就能把某场考试提高1分。你能给每场考试选择一个$[l_i,u_i]$之间的加权。求最少花多少小时才能不比对手低

$n, X, l_i, u_i \leq 10^5, b_i \leq X$

简单的二分。

首先最多只会有一场考试不是0分或X分,因为如果有两场考试都是$>0, <X$的话,一定可以把其中一场考试分数分给另外一场考试一些会更优。

然后枚举一下那个不是0分或X分的考试就行了。剩下的,提前排好序,贪心选最好的几个。

我场上大概是sb。最开始想到过二分,后来想到了那个结论,却又忘了二分,一直在想怎么动态维护些东西,没把二分和结论两个合起来想。

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
int n;
long long X, D;

struct Node{
	long long x, l, r, num;
	bool operator <(const Node &b) const{
		return num > b.num;
	}
}node[maxn];
long long sum[maxn];

bool check(long long x) {
	int d = x / X, o = x % X;
	long long now = 0;
	for (int i = 1; i <= n; ++i) {
		if(o < node[i].x) now = (o - node[i].x) * node[i].l;
		else now = (o - node[i].x) * node[i].r;
		if(i <= d) now += sum[d + 1] - node[i].num + node[i].x * node[i].l;
		else now += sum[d] + node[i].x * node[i].l;
		if(now >= D) return 1;
	}
	return 0;
}

int main() {
	scanf("%d%lld", &n, &X);
	long long l = -1, r = 0, mid;
	for (int i = 1; i <= n; ++i) {
		scanf("%lld%lld%lld", &node[i].x, &node[i].l, &node[i].r);
		node[i].num = node[i].x * node[i].l;
		D += node[i].num;
		node[i].num += (X - node[i].x) * node[i].r;
		r += node[i].x;
	}
	sort(node + 1, node + n + 1);
	for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + node[i].num;
	while(l < r - 1) {
		mid = (l + r) >> 1;
		if(check(mid)) r = mid;
		else l = mid;
	}
	printf("%lld\n", r);
	return 0;
}

  

当年AGC都是从D开始做的,现在经常C甚至B都不会,难受死了,越来越退步了。

老张还想让我回学校给学弟讲课,别想了,太菜了,就这水平到底是学弟教我还是我教学弟啊。。。

前两天Yyyyyyyk来my和我一起玩,玩得挺开心的,聊了一整天。感觉挺奇妙的,当初一届一起学OI的,基本上都去了BJ和SH,却几乎没人再打ACM了。而我呢,本来也是不愿再碰,但是那天纠结了很久,就是有点不甘心啊。从OI到ACM,一个Au都没有。学OI的时候,无论是CTSC、APIO、NOI,真的一个Au都没有。而去年打ACM,无论ICPC还是CCPC还是国外的ICPC,不是Ag就是Cu。高一就有的Au梦,到大一还没能实现。于是我这个蒟蒻厚颜无耻地留下来了,训练垫底什么的也早已习惯。

前段时间期末那阵,楼上装修电钻啥的吵死人了,而且经常熬夜,晚上睡不好啥的,白天要睡午觉也经常被吵得睡不着,最近也经常半夜惊醒或者失眠或者一下子睡很久感觉都睡不够。现在的状态真的太差了。太差了。想早点回学校

posted @ 2020-07-28 21:55  shixinyi  阅读(213)  评论(0编辑  收藏  举报