• 传送门
  • 考场上的思路
  • 正解
  • 参考代码
传送门
考场上的思路

  首先按照 b 排序,然后就相当于是考虑 a 在排序后组成的最大矩形(差不多那个意思)。发现加入一个数就等价于将小于它的所有数对应的答案加上它们自己,自然地想到了每个结点带有权重的线段树,却发现这种线段树只适合于求和,不适合于取最大值。也想到过分块和单调数据结构,但是失败了……

正解

  我们维护当 p=pip=pip = p_i 时的最大收益。这样,插入一个数,就等于将小于等于它的数加上它们本身这么多的贡献。现在的问题是,如何找出最大值。

  可以使用分块。当我们对一整块进行操作时,就给这个块的标记加 1,对于剩下的,暴力维护即可。怎么计算整块的最大值呢?假设目前整块中的某个位置的值为 val[i],那么它实际上的值应该是 vai[i] + i * tag[inBlock[i]]。发现,所有的值都可以写成如下形式:

vali=k⋅i+val′ivali=k⋅i+val′i

\mathrm{val}_i = k \cdot i + \mathrm{val'}_i

  考虑使用单调队列维护这个东西。当 tag 增加时,我们弹出队首的更劣解。但是怎么构建这个单调队列呢?我们只最在暴力重构时构建它,这里需要用到一些斜率优化的方法使得解正确。

  设 i<j<ki<j<ki 且在同一块中,若 jjj 比 i" role="presentation" style="position: relative;">iii 更优,则有:

vali+i⋅tag<valj+j⋅tagvali+i⋅tag<valj+j⋅tag

\mathrm{val}_i + i \cdot \mathrm{tag}

  即:

vali−valjj−i<tagvali−valjj−i<tag

\frac {\mathrm{val}_i - \mathrm{val}_j} {j - i}

  当 vali−valjj−i>valj−valkk−jvali−valjj−i>valj−valkk−j\frac {\mathrm{val}_i - \mathrm{val}_j} {j - i} > \frac {\mathrm{val}_j - \mathrm{val}_k} {k - j} 时,jjj 永远不会是最优值(斜率优化),这时弹出队尾即可。

参考代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <climits>
#include <cctype>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef LL INT_PUT;
INT_PUT readIn()
{INT_PUT a = 0;bool positive = true;char ch = getchar();while (!(ch == '-' || std::isdigit(ch))) ch = getchar();if (ch == '-'){positive = false;ch = getchar();}while (std::isdigit(ch)){a = a * 10 - (ch - '0');ch = getchar();}if (positive) a = -a;return a;
}
void printOut(INT_PUT x)
{char buffer[20];int length = 0;if (x < 0) putchar('-');else x = -x;do buffer[length++] = -(x % 10) + '0'; while (x /= 10);do putchar(buffer[--length]); while (length);putchar(' ');
}const int maxn = int(1e5) + 5;
int n, w;
struct People
{int a;int b;void read(){a = readIn();b = readIn();}bool operator<(const People& y) const{return b < y.b;}
} people[maxn];
int maxa, maxb;#define RunInstance(x) delete new x
struct brute
{brute(){std::sort(people + 1, people + 1 + n);int cnt = 1;std::multiset<int> A;for (int c = 1, to = maxb + 1; c <= to; c++){while (cnt <= n && c > people[cnt].b){A.insert(people[cnt].a);cnt++;}LL ans = 0;int j = 0;int size = A.size();for (std::multiset<int>::iterator it = A.begin(); it != A.end(); it++)ans = std::max(ans, (LL)(size - (j++)) * *it);ans += (LL)(n - cnt + 1) * c * w;printOut(ans);}}
};
struct work
{int inBlock[maxn];int lBegin[maxn];int rEnd[maxn];int sqrtN;int N;void initBlocks(){sqrtN = std::sqrt(maxa);N = maxa / sqrtN + 1;for (int i = 0; i <= maxa; i++){int t = inBlock[i] = i / sqrtN;if (!lBegin[t]) lBegin[t] = i;rEnd[t] = i;}}static const int maxN = 455;std::deque<int> mono[maxN];int tag[maxN];LL val[maxn];LL ans;void maintain(int v){int block = inBlock[v];for (int i = 0; i < block; i++){tag[i]++;std::deque<int>& q = mono[i];while (q.size() >= 2 && val[q.front()] + (LL)q.front() * tag[i] <= val[q[1]] + (LL)q[1] * tag[i])q.pop_front();if (q.size())ans = std::max(ans, val[q.front()] + (LL)q.front() * tag[i]);}for (int i = lBegin[block], to = rEnd[block]; i <= to; i++)val[i] += (LL)i * tag[block];tag[block] = 0;for (int i = lBegin[block]; i <= v; i++)val[i] += i;std::deque<int>& q = mono[block];q.clear();for (int i = lBegin[block], to = rEnd[block]; i <= to; i++){while (q.size() >= 2 &&(double)(val[q[q.size() - 2]] - val[q.back()]) / (q.back() - q[q.size() - 2]) > (double)(val[q.back()] - val[i]) / (i - q.back()))q.pop_back();q.push_back(i);ans = std::max(ans, val[i]);}}work() : lBegin(), tag(), val(), ans(){initBlocks();std::sort(people + 1, people + 1 + n);int cnt = 1;for (int c = 1, to = maxb + 1; c <= to; c++){while (cnt <= n && c > people[cnt].b){int a = people[cnt].a;cnt++;maintain(a);}printOut(ans + (LL)(n - cnt + 1) * c * w);}}
};void run()
{n = readIn();w = readIn();for (int i = 1; i <= n; i++){people[i].read();maxa = std::max(maxa, people[i].a);maxb = std::max(maxb, people[i].b);}if ((LL)n * maxb <= LL(1e8))RunInstance(brute);elseRunInstance(work);
}int main()
{
#ifndef LOCALfreopen("laofu.in", "r", stdin);freopen("laofu.out", "w", stdout);
#endifrun();return 0;
}

  时间复杂度为 O(nn)" role="presentation" style="position: relative;">O(nn−−√)O(nn)O(n \sqrt n)。

JZOJ 5585 老夫相关推荐

  1. JZOJ 5461 购物 —— 贪心

    题目:https://jzoj.net/senior/#main/show/5461 贪心,原来想了个思路,优先选优惠价最小的 K 个,然后其他按原价排序遍历: 如果当前物品没选过,原价选上,如果选过 ...

  2. 【正一专栏】老夫老妻了,你还会说我爱你吗?

    老夫老妻了,你还会说我爱你吗? 九天时空 对于离婚.出轨.小三这样的话题真是不能展开太多,面对这个世界形形色色的诱惑,婚姻不过柴米油盐.时间久了,难免会让人有些想法.在如今这样一个以金钱至上的世界,能 ...

  3. JZOJ 5372. 【NOIP2017提高A组模拟9.17】猫

    Description 信息组最近猫成灾了!隔壁物理组也拿猫没办法.信息组组长只好去请神刀手来帮他们消灭猫.信息组现在共有n 只猫(n 为正整数),编号为1 到n,站成了一个环,第i 只猫的左边是第i ...

  4. [jzoj NOIP2018模拟 11.01]

    很庆幸打了这场模拟赛,因为这一场爆零 好像上次纪中的某场比赛我也出现了同样的问题,光是计算时间复杂度而忘记了空间的限制.想必是比上次惨的,考场上就写了两题而这两题都因为MLE爆零了.而且我T2还码了7 ...

  5. 【DP】小学生语文题(jzoj 5102)

    正题 jzoj 5102 题目大意 给你两个串A,B,字母个数相等,可以把B的一个字符移到前面某个位置,问你最少移多少次可以使A,B相等 解题思路 设fi,jf_{i,j}fi,j​为A匹配了i-n, ...

  6. 【二分】防具布置/秦腾与教学评估(ybtoj 二分-1-2/jzoj 1253/luogu 4403)

    正题 ybtoj 二分-1-2 jzoj 1253 luogu 4403 题目大意 给出n组数:si,ei,dis_i,e_i,d_isi​,ei​,di​ 对于每组数据,表示在sis_isi​加1, ...

  7. 【归并排序】奶牛的图片(jzoj 1812)

    奶牛的图片 jzoj 1812 题目大意 给你一个序列,你可以交换相邻的两个数 让你用最少的交换次数来使得这个序列变成形如a+1,a+2...n,1,2...a−1,aa+1,a+2...n,1,2. ...

  8. 【归并排序】休息(jzoj 3462)

    休息 jzoj 3462 题目大意 给你一个序列,你每一回合把它划分成尽可能少的单调递减的序列(第一次划分到的序列长度都是偶数),然后把每个序列翻转,问你把它变成单调递增的序列要翻转多少次 输入样例 ...

  9. 秀姿势(jzoj 3464)

    秀姿势 jzoj 3464 题目大意 有n个数,每个数都有一个分组,现在问你最多去掉k个分组后,做多有多少个数是连续的同组的 输入样例 9 1 2 7 3 7 7 3 7 5 7 输出样例 4 样例解 ...

最新文章

  1. Maven的setting.xml配置文件详解(中文)
  2. python子类如何继承父类的实例变量?
  3. iOS 证书、密钥及信任服务
  4. 《Python语言程序设计》——1.6 开始学习Python
  5. python获取手机通知栏消息_Python编写简单的通知栏脚本启动工具
  6. 关于WAP技术的介绍
  7. 安装Editplus软件
  8. 安装SQL Server 2016及一些常用操作
  9. Mybatis_select、insert、update、delete常用属性
  10. 域名解析不生效,中科三方带你定位!
  11. Mybatis【面试题】
  12. JavaWeb学习-案例练习-图书管理后台-5- 完成图书删除功能
  13. 一名职业3D建模师的学习经历,月薪28K依然焦虑
  14. 汽车电子环境基本阐述
  15. 计算机系统应用的书,基于个性化图书推荐的协同过滤算法
  16. 2022大三计算机 | 保研机试 | 学习路线
  17. 项目优化:当使用redis减少数据库压力时,遇到redis写入失败,造成读取数据问题的解决方案
  18. elementUI脚手架
  19. 软件工程导论作业2.3
  20. EXCEL vba工程密码破解

热门文章

  1. 如何用python画一束花_如何在AI里绘制一束春天的花朵
  2. 深度学习人脸检测与人脸识别
  3. HDU-2545 树上战争
  4. matlab 固态硬盘,电脑内存和固态硬盘有什么区别 电脑内存和固态硬盘对比【详解】...
  5. 笔记本电脑硬件软件全升级:内存条-固态硬盘-重装系统
  6. 台式计算机内存卡与普通有啥区别,电脑硬盘和内存有什么区别?
  7. 双稳态电子开关、单按键自锁电路仿真
  8. OCC-7.6.0 + MFC单文档应用入门教程
  9. WM_KILLFOCUS和WM_SETFOCUS
  10. Qt的.pro工程文件语法学习