\(\mathcal{Description}\)

  Link.

  给定非负整数序列 \(\{l_n\},\{r_n\},\{b_n\},X\),求最小的 \(s\),使得存在非负整数序列 \(\{a_n\},\{c_n\}\),满足 \(a_i\le X\),\(\sum_{i=1}^na_i=s\),\(c_i\in[l_i,r_i]\),且

\[\sum_{i=1}^nc_i(a_i-b_i)\ge0
\]

  所有输入均 \(\le10^5\)。

\(\mathcal{Solution}\)

  显然二分 \(s\),仅需做到检测某个 \(s\) 是否合法。下令 \(w=\sum_{i=1}^nc_ia_i\)。

  假设 \(\{a_n\}\) 已经确定,那么所有满足 \(a_i\ge b_i\) 的 \(c_i=r_i\),其余 \(c_i=l_i\)。考虑初始时所有 \(a_i=0,c_i=l_i\),现在把 \(s\) 个 \(1\) 挨个加到一些 \(a_i\) 上。当 \(a_i<b_i\) 时,对 \(w\) 贡献 \(l_i\)(此时 \(c_i\) 仍取 \(l_i\));当 \(a_i=b_i\) 时,对 \(w\) 贡献由 \(l_i\) 转为 \(r_i\)(\(c_i\) 变成 \(r_i\));继续增加,对 \(w\) 贡献 \(r_i\)。最终仅需比较 \(w\) 和 \(\sum_{i=1}^nl_ib_i\) 的大小。

  所以问题抽象为:有 \(n\) 个分段函数 \(f_{1..n}(x)\),满足

\[f_i(x)=\begin{cases}l_ix&x\in[0,b_i]\cap\mathbb N\\
l_ib_i+r_i(x-b_i)&x\in(b_i,X]\cap\mathbb N
\end{cases}
\]

  仅需钦定 \(\{x_n\}\),使得 \(\sum_{i=1}^nf_i(x_i)\) 取最大。

  考虑贪心,不难证明:至多有一个 \(0<x_i<X\)。直接枚举哪一个 \(0<x_i<X\),贪心地选取最大的 \(f_i(X)\),即可 \(\mathcal O(n)\) 检测。最终复杂度 \(\mathcal O(n\log\sum_{i=1}^nb_i)\)。

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>
#include <algorithm> #define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i ) inline int rint () {
int x = 0, f = 1; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x * f;
} typedef long long LL; const int MAXN = 1e5;
int n, x, b[MAXN + 5], l[MAXN + 5], r[MAXN + 5], ord[MAXN + 5];
LL full[MAXN + 5]; inline LL contr ( const int i, const int s ) {
return s <= b[i] ? 1ll * s * l[i]
: 1ll * l[i] * b[i] + 1ll * ( s - b[i] ) * r[i];
} inline void init () {
std::sort ( ord + 1, ord + n + 1, []( const int i, const int j ) {
return contr ( i, x ) > contr ( j, x );
} );
rep ( i, 1, n ) full[i] = full[i - 1] + contr ( ord[i], x );
} inline LL calc ( const LL scr ) {
/*
* let's come up with a greedy algorithm!
* */
int fcnt = scr / x, rest = scr % x;
LL ret = 0;
rep ( i, 1, n ) { // score on exam <ord[i]> is <rest>.
LL cur = contr ( ord[i], rest );
if ( i > fcnt ) cur += full[fcnt];
else cur += full[fcnt + 1] - contr ( ord[i], x );
ret = cur > ret ? cur : ret;
}
return ret;
} int main () {
n = rint (), x = rint ();
LL sum = 0, sb = 0;
rep ( i, 1, n ) {
ord[i] = i;
b[i] = rint (), l[i] = rint (), r[i] = rint ();
sum += 1ll * b[i] * l[i], sb += b[i];
}
init ();
LL lef = 0, rig = sb;
while ( lef < rig ) {
LL mid = lef + rig >> 1;
if ( calc ( mid ) >= sum ) rig = mid;
else lef = mid + 1;
}
printf ( "%lld\n", lef );
return 0;
}

最新文章

  1. [CareerCup] 5.7 Find Missing Integer 查找丢失的数
  2. Java_动态编译总结
  3. Freemaker 自定义函数
  4. selenium webdriver学习(一)
  5. [WinAPI] 串口读写
  6. Fiddler录制jmeter脚本,干货分享
  7. [terry笔记]RMAN综合学习之配置
  8. C# 中通过API实现的打印类
  9. iOS开发--使用NSMutableAttributedString 实现富文本
  10. light oj 1019【最短路模板】
  11. 学习C++——只声明忘记定义了
  12. 09-使用for循环输出空心菱形(循环)
  13. COCOA&#174; PROGRAMMING FOR MAC&#174; OS X (2)- Speak Line
  14. C# Sap Rfc 连接代码实例
  15. HttpInvoker客户端动态调用Demo
  16. Confluence 6 配置白名单
  17. CSS水平居中的三种方法
  18. iOS 处理缓存的三种方法
  19. JDK1.6官方下载_JDK6官方下载
  20. maven学习系列 之 常见问题

热门文章

  1. Java 单引号 与 双引号 区别
  2. js获取设备内网ip
  3. Pandas系列(十七)-EDA(pandas-profiling)
  4. 万级K8s集群背后 etcd 稳定性及性能优化实践
  5. JAVA之G1垃圾回收器
  6. 【PTA】6-1 **删除C程序中的注释 (31 分)
  7. Qt之进入和出去和关闭事件
  8. golang中goroutine
  9. golang中结构体的嵌套、方法的继承、方法的重写
  10. Python36 使用Redis 构建分布式爬虫(未完)