@description@

在这道题种你需要解决一个全世界人类从存在起就在面临的最深刻的问题--如何发大财。

你是一名零件交易市场的中介。你的工作是从零件生产公司那里买到零件,然后把它们卖给零件消费公司。

每个零件消费公司在截止日期前每天都会对一个零件有一个开放式的需求,以及它愿意买下零件的价格。另一方面,每个零件生产公司在开始日期及以后都可以销售零件,以及它销售零件的价格。基于公平竞争法,你只能与一家生产公司、一家消费公司签订合同。

你可以在生产公司开始销售后每天从生产公司买一个零件,当然这也要在消费公司结束需求之前。

在这些天里,每天你可以从买卖差价中获取利润。你的任务是选择能使你利益最大化的生产公司与消费公司。

1≤m,n≤500 000

原题戳这里0.0

@solution@

实际上就是求 max{(qj - pi)*(ej - di) | ej > di}。

将 (qj, ej) 与 (pi, di) 都看成二维平面中的点,则相当于求以 (qj, ej) 为右上角,(pi, di) 为左下角的最大矩形面积。

注意到当 qk <= qj 且 ek <= ej 时,(qj, ej) 比 (qk, ek) 更容易合法且在更优,此时 k 就没有用了。

同理,当 pi <= pk 且 di <= dk 时,(pi, di) 比 (pk, dk) 一定更好。

所以最终两个序列的有用点一定是横坐标单增的同时纵坐标单减。

不会做了。于是考虑决策单调性。手推了一下式子发现的确有决策单调性(这里就不推了,挺好推的)。

然而。。。如果仅仅这样就结束了我才不会写这篇博客作为教训。。。

注意到每个点 (qj, ej) 的决策是有范围:对应的 i 要满足 pi < qj, di < ej。否则决策单调性的式子就推不出来了(?应该是吧,因为有点久了所以不是很确定)。

而这些 i 构成了一个区间 [le(j), ri(j)],其中 le(j) 的纵坐标 < ej 且最小,ri(j) 的横坐标 < pi 且最大。

而假如你像我一样采用分治法,那么就会遇到一个问题:有可能当前分治的决策点区间 [opl, opr] 与我们 mid 的决策范围没有交集。。。

而这又有几种情况:一种是 le(mid) > ri(mid),即 mid 本身没有决策的点。此时分治 [opl, ri(mid)] 与 [le(mid), opr],可以保证时间复杂度与正确性。

另外两种其实是类似的,一种是 le(mid) > opr,此时把 [opl, opr] 传给 [l, mid-1] 即可;还有一种是 ri(mid) < opl,反过来传给右边的 [mid, r] 即可。

@accepted code@

  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4. const int MAXN = 500000;
  5. typedef long long ll;
  6. struct node{
  7. int x, y;
  8. node(int _x=0, int _y=0) : x(_x), y(_y) {}
  9. friend bool operator < (node a, node b) {
  10. return (a.x == b.x) ? a.y < b.y : a.x < b.x;
  11. }
  12. }t[MAXN + 5], a[MAXN + 5], b[MAXN + 5];
  13. ll ans;
  14. int le[MAXN + 5], ri[MAXN + 5];
  15. void solve(int opl, int opr, int l, int r) {
  16. if( l > r ) return ;
  17. int m = (l + r) >> 1, opm = opl;
  18. if( ri[m] < opl ) solve(opl, opr, m + 1, r);
  19. else if( le[m] > opr ) solve(opl, opr, l, m - 1);
  20. else if( le[m] > ri[m] ) {
  21. solve(opl, ri[m], l, m - 1);
  22. solve(le[m], opr, m + 1, r);
  23. }
  24. else {
  25. ll res = -1;
  26. for(int i=opl;i<=opr;i++) {
  27. ll t = 1LL*(b[m].x - a[i].x)*(b[m].y - a[i].y);
  28. if( b[m].x >= a[i].x && b[m].y >= a[i].y && t >= res )
  29. opm = i, res = t;
  30. }
  31. ans = max(ans, res);
  32. solve(opl, opm, l, m - 1);
  33. solve(opm, opr, m + 1, r);
  34. }
  35. }
  36. int m, n, ca, cb;
  37. int main() {
  38. scanf("%d%d", &m, &n);
  39. for(int i=1;i<=m;i++) {
  40. int p, d; scanf("%d%d", &p, &d);
  41. t[i] = node(p, d);
  42. }
  43. sort(t + 1, t + m + 1);
  44. for(int i=1;i<=m;i++) {
  45. if( !ca || !(t[i].x >= a[ca].x && t[i].y >= a[ca].y) )
  46. a[++ca] = t[i];
  47. }
  48. for(int i=1;i<=n;i++) {
  49. int q, e; scanf("%d%d", &q, &e);
  50. t[i] = node(q, e);
  51. }
  52. sort(t + 1, t + n + 1);
  53. for(int i=1;i<=n;i++) {
  54. while( cb && t[i].x >= b[cb].x && t[i].y >= b[cb].y )
  55. cb--;
  56. b[++cb] = t[i];
  57. }
  58. le[0] = 1, ri[0] = 0;
  59. for(int i=1;i<=n;i++) {
  60. le[i] = le[i-1], ri[i] = ri[i-1];
  61. while( le[i] <= m && a[le[i]].y > b[i].y ) le[i]++;
  62. while( ri[i] < m && a[ri[i]+1].x <= b[i].x )
  63. ri[i]++;
  64. }
  65. solve(1, ca, 1, cb);
  66. printf("%lld\n", ans);
  67. }

@details@

比较详细的细节都在 solution 里面说啦。

@bzoj - 4951@ [Wf2017]Money for Nothing的更多相关文章

  1. bzoj 4951: [Wf2017]Money for Nothing【分治】

    参考:https://blog.csdn.net/herobrine_tkj/article/details/78404426?locationNum=8&fps=1 为什么从1开始存就挂了, ...

  2. BZOJ 4951 [WF2017]Money for Nothing (决策单调优化DP+分治)

    题目大意:略 题目传送门 不愧是$World final$的神题,代码短,思维强度大,细节多到吐..调了足足2h 贪心 我们利用贪心的思想,发现有一些工厂/公司是非常黑心的 以工厂为例,对于一个工厂$ ...

  3. 4951: [Wf2017]Money for Nothing 决策单调性 分治

    Bzoj4951:决策单调性 分治 国际惯例题面:一句话题面:供应商出货日期为Ei,售价为Pi:用户收购截止日期为Si,收购价格为Gi.我们要求max((Si-Ej)*(Gi-Pj)).显然如果我们把 ...

  4. 【刷题】BZOJ 4950 [Wf2017]Mission Improbable

    Description 那是春日里一个天气晴朗的好日子,你准备去见见你的老朋友Patrick,也是你之前的犯罪同伙.Patrick在编程竞赛上豪赌输掉了一大笔钱,所以他需要再干一票.为此他需要你的帮助 ...

  5. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  6. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  7. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  8. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. MATLAB技巧—sort和sortrows函数

    MATLAB技巧-sort和sortrows函数 1.sort函数 sort函数用于对数据进行排序,通过help sort命令,可以查找到sort函数的具体用法: Y = SORT(X,DIM,MOD ...

  2. 【JZOJ5179】【NOI2017模拟6.29】哈哈

    题意 给定一个长度为n的序列,你可以进行若干次操作: 选择一个区间,删掉,并获得Val[Len]的得分,Len为这个区间的长度: 其中这个区间满足: 1.相邻两个数差的绝对值为1 2.每个数都大于相邻 ...

  3. JQuery学习:事件绑定&入口函数&样式控制

    1.基础语法学习: 1.事件绑定 2.入口函数 3.样式控制 <!DOCTYPE html> <html lang="en"> <head> & ...

  4. .NET CORE中Encoding对GB2312等编码的支持

    最近.NET CORE做网络爬虫的时候,遇到了charset=gbk,转码的时候,发现直接使用Encoding.GetEncoding(“GB2312”)抛异常了.好吧,看到这个的时候,我是一脸懵逼的 ...

  5. LintCode_514 Paint Fence

    题目 here is a fence with n posts, each post can be painted with one of the k colors.You have to paint ...

  6. 汉诺塔III HDU - 2064

    汉诺塔III HDU - 2064   约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右 ...

  7. 【模板】KMP [2017年5月计划 清北学堂51精英班Day2]

    Day2就搞一个KMP把  马拉车.AC自动机等准备省选的时候再说.. 模板题: 1204 寻找子串位置 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze     ...

  8. Codeforces 1150D(字符串dp)

    反思 三维的dp压根没看出来,看题解以后思路又很直观,找几道字符串dp练练才行 序列自动机和优化一维略 /* __ __ * ____| |_____| |____ * | | * | __ | * ...

  9. Leetcode120.Triangle三角形最小路径和

    给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径和为 11 ...

  10. Django快速创建新项目

    Python免费视频含配套文件QQ124111294 https://pan.baidu.com/s/1bL5ml4 python.exe manage.py startapp app01 pytho ...