@description@

今天是 IOI 酱的生日,所以她的哥哥 JOI 君给她预定了一个生日蛋糕。虽然他计划买一整个蛋糕,但是他不小心订成了
N

块蛋糕。这
N

块蛋糕编号为
1\ldots N

,每块蛋糕都有价值和颜色。第
i

块蛋糕的价值为
V_i

,颜色深度为
C_i

为了做成一整块蛋糕,他决定选择
M

块互不相同的蛋糕,然后将它们按一定顺序排成一个环。整块蛋糕的美观程度定义如下:

\sum_{j=1}^M V_{k_j}-\sum_{j=1}^M|C_{k_j}-C_{k_{j+1}}|

其中,他选择了编号为
k_1,\ldots ,k_M

的蛋糕(这里令
k_{M+1}=k_1

)。换句话说,整个蛋糕的美观程度为选择蛋糕的价值和与所有相邻两块蛋糕颜色深度差的绝对值之和的差。JOI 君想要让整块蛋糕尽可能美观。

写一个程序,在给定蛋糕的块数,选择蛋糕的数目和每块蛋糕的价值和颜色深度的情况下,计算 JOI 君做成的蛋糕的最大美观度。

@solution@

首先考虑选定蛋糕后,如何编排美观度最大,因为编排只会影响 \(-\sum_{j=1}^{M}|C_{k_j} - C_{k_{j+1}}|\) 的大小,所以只需要它最大即可。

考虑每个 C 的贡献,可以将上式写作 \(-\sum_{j=1}^{M}(a_j + b_j)*C_{k_j}\),其中 \(a_j, b_j\) 为 1 或 -1,是通过拆绝对值得到的。

由于 a, b 是拆绝对值得到的,所以最大值对应的 a = b = 1,最小值对应的 a = b = -1;同时 ∑(a+b) = 0。

我们可以证明,除最大值与最小值以外,其他数取 a = 1, b = -1 最优。假如更改一个数的 b = 1,则必然有一个比它小的数的 a 更改为 -1,而这是不优的。

所以可以等价地转为使 \(\sum_{j=1}^{M}V_{k_j} - 2*(\max\{C_{k_j}\} - \min\{C_{k_j}\})\) 最大。

考虑将所有蛋糕按 C 排序。然后我们去枚举最大值的上界 C[r] 和最小值的下界 C[l](如果是枚举最大值则要保证那个值必须选择,后面的处理就不大方便)。

则我们选择的 M 块蛋糕要在区间 [l, r] 中选择。因为 C 已经固定,我们需要 V 的和最大,显然是选择区间内前 M 大的 V 求和。

则一个区间 [l, r] 的贡献 = 区间内 V 值前 M 大之和 - 2*(C[r] - C[l])。枚举区间并计算需要 O(n^2*logn) 的时间复杂度。

然后考虑优化。我们可以从决策单调性的方面入手。因为考虑了一会儿发现没啥地方可以下手的,于是生成一点随机数据打个表惊讶地发现它有决策单调性。

如果知道了它有决策单调性,用单调栈+二分或者分治找决策点都可以,用可持久化权值线段树计算,时间复杂度降为 O(n*log^2n)。

大概感性证明一下单调性。我们只需要证明如果 p < q <= i 且区间 [q, i] 优于 [p, i],则区间 [q, i+1] 优于 [p, i+1]。

记 f(l, r) 表示区间 [l, r] 内 V 值前 M 大之和。由题设可得 f(q, i) - 2*(C[i] - C[q]) >= f(p, i) - 2*(C[i] - C[p]),即 f(q, i) - f(p, i) >= 2*C[p] - 2*C[q]。

因为 f(l, r) 有一个性质:对于 p < q <= i,有 f(q, i+1) - f(q, i) >= f(p, i+1) - f(p, i)。这个性质直观上感知不难,详细证明需要讨论区间 [p, i], [q, i] 中的最小值与 V[i+1] 的关系。

于是 f(q, i+1) - f(p, i+1) >= f(q, i) - f(p, i) >= 2*C[p] - 2*C[q],从而得到结论 f(q, i+1) - 2*(C[i+1] - C[q]) >= f(p, i+1) - 2*(C[i+1] - C[p])。

@accepted code@

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 200000;
const ll INF = (1LL<<60);
struct segtree{
struct node{
node *ch[2];
int cnt; ll sum;
}pl[20*MAXN + 5], *rt[MAXN + 5], *ncnt, *NIL;
segtree() {rt[0] = ncnt = NIL = &pl[0]; NIL->ch[0] = NIL->ch[1] = NIL;}
node *insert(node *pre, int l, int r, int p, ll k) {
node *nw = (++ncnt); (*nw) = (*pre);
nw->cnt++, nw->sum += k;
if( l == r ) return nw;
int mid = (l + r) >> 1;
if( p <= mid ) nw->ch[0] = insert(pre->ch[0], l, mid, p, k);
else nw->ch[1] = insert(pre->ch[1], mid + 1, r, p, k);
return nw;
}
ll query(node *L, node *R, int p) {
if( !p ) return 0;
if( R->ch[0] == NIL && R->ch[1] == NIL )
return R->sum/R->cnt*p;
if( R->ch[1]->cnt - L->ch[1]->cnt > p )
return query(L->ch[1], R->ch[1], p);
else
return query(L->ch[0], R->ch[0], p - (R->ch[1]->cnt - L->ch[1]->cnt)) + R->ch[1]->sum - L->ch[1]->sum;
}
}T;
struct cake{
int V, C;
friend bool operator < (cake a, cake b) {
return a.C < b.C;
}
}ck[MAXN + 5];
int N, M;
ll get_ans(int l, int r) {
return T.query(T.rt[l-1], T.rt[r], M) - 2*(ck[r].C - ck[l].C);
}
ll ans = -INF; int pnt[MAXN + 5];
int get_point(int l, int r, int x) {
int p = l; ll k = get_ans(p, x);
for(int i=l+1;i<=r&&x-i+1>=M;i++) {
ll q = get_ans(i, x);
if( q > k )
p = i, k = q;
}
ans = max(ans, k);
return pnt[x] = p;
}
void solve(int L, int R, int le, int ri) {
if( L > R ) return ;
int mid = (L + R) >> 1, p = get_point(le, ri, mid);
solve(L, mid - 1, le, p);
solve(mid + 1, R, p, ri);
}
int d[MAXN + 5], dcnt = 0;
int main() {
scanf("%d%d", &N, &M);
for(int i=1;i<=N;i++)
scanf("%d%d", &ck[i].V, &ck[i].C), d[++dcnt] = ck[i].V;
sort(ck + 1, ck + N + 1);
sort(d + 1, d + dcnt + 1), dcnt = unique(d + 1, d + dcnt + 1) - d - 1;
for(int i=1;i<=N;i++)
T.rt[i] = T.insert(T.rt[i-1], 1, N, lower_bound(d + 1, d + dcnt + 1, ck[i].V) - d, ck[i].V);
solve(M, N, 1, N - M + 1);
printf("%lld\n", ans);
}

@details@

好久没有写可持久化权值线段树求第 k 大(我写过吗),结果没有处理好存在相同的值的时候怎么办。。。WA 了好几发。。。

然后就是注意区间 [l, r] 的长度必须 >= M,不然也会 WA。。。

@loj - 3039@ 「JOISC 2019 Day4」蛋糕拼接 3的更多相关文章

  1. 「JOISC 2019 Day4」蛋糕拼接 3

    loj 3039 NKOJ Description \(n\)个蛋糕,每个蛋糕有\(w_i,h_i\).选\(m\)个蛋糕满足\(\sum\limits_{j=1}^mw_{k_j}-\sum\lim ...

  2. LOJ#2882. 「JOISC 2014 Day4」两个人的星座(计算几何)

    题面 传送门 题解 我们发现如果两个三角形相离,那么这两个三角形一定存在两条公切线 那么我们可以\(O(n^2)\)枚举其中一条公切线,然后可以暴力\(O(n^3)\)计算 怎么优化呢?我们可以枚举一 ...

  3. 【LOJ】#3036. 「JOISC 2019 Day3」指定城市

    LOJ#3036. 「JOISC 2019 Day3」指定城市 一个点的可以dp出来 两个点也可以dp出来 后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可 #include < ...

  4. 【LOJ】#3034. 「JOISC 2019 Day2」两道料理

    LOJ#3034. 「JOISC 2019 Day2」两道料理 找出最大的\(y_{i}\)使得\(sumA_{i} + sumB_{y_i} \leq S_{i}\) 和最大的\(x_{j}\)使得 ...

  5. 【LOJ】#3032. 「JOISC 2019 Day1」馕

    LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...

  6. 【LOJ】#3033. 「JOISC 2019 Day2」两个天线

    LOJ#3033. 「JOISC 2019 Day2」两个天线 用后面的天线更新前面的天线,线段树上存历史版本的最大值 也就是线段树需要维护历史版本的最大值,后面的天线的标记中最大的那个和最小的那个, ...

  7. 【LOJ】#3031. 「JOISC 2019 Day1」聚会

    LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...

  8. 【LOJ】#3030. 「JOISC 2019 Day1」考试

    LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...

  9. 「JOISC 2019 Day3」穿越时空 Bitaro

    「JOISC 2019 Day3」穿越时空 Bitaro 题解: ​ 不会处理时间流逝,我去看了一眼题解的图,最重要的转换就是把(X,Y)改成(X,Y-X)这样就不会斜着走了. ​ 问题变成二维平面上 ...

随机推荐

  1. FreeMarker 获取页面appplication、request、session

    使用Request里的Attribute值最简单的方法就是直接${AttributeName}或者安全一点:${AttributeName!"default Value"} 1.取 ...

  2. php 获取一张图片所有点的颜色值

    image_all_rgb.php <?php //similar_text($numStr, $val, $pre); //计算两个字符串的相似度 //print_r($pre); $imgP ...

  3. NOIP模拟赛 17.10.10

    初次见面(firstmeet)[题目背景]雾之湖边,静得可怕.露米娅出神凝望.黑白连衣裙,像极了绽放的墨黑和洁白的莲.身边的雾之湖,倒映着血色天空.酒红的双眸,映照一切.低声浅笑,双臂伸直,她悄无声息 ...

  4. SourceTree windows免注册免登陆使用方法

    问题描述: 安装SourceTree后,首次使用时,需要登录账号:但我们在注册或登录时,可能根本无法打开网页,导致不能进入. 如下截图: 解决方法: 在目录C:\Users\XXXXX\AppData ...

  5. 【二次元的CSS】—— 用 DIV + CSS3 画咸蛋超人(详解步骤)

    [二次元的CSS]—— 用 DIV + CSS3 画咸蛋超人(详解步骤) 2016-05-17 HTML5cn 仅仅使用div作为身体的布局,用css3的各种transform和圆角属性来绘制各部位的 ...

  6. 小米网关api

    http://bbs.xiaomi.cn/t-13198850 https://github.com/snOOrz/homebridge-aqara/blob/master/README.md htt ...

  7. Header解析

    不管是作为后端还是前端开发人员,对于web请求的过程和参数都是需要了解的. 下面是对一次简单的http请求的header分析,作为自己的一个总结,也希望对大家有所帮助. 以Chrome为例: 我们对h ...

  8. HTML之meta标签缓存控制

    <meta http-equiv="pragram" content="no-cache"> 禁止浏览器从本地缓存中调阅页面. 网页不保存在缓存中, ...

  9. Python subn函数

  10. BZOJ 4817数点涂色题解

    题目链接 考试考了一道类似的题目,然后不争气的挂掉了,于是跑过来学习这道题的解法... 我还是太菜了.... 我们可以发现任意时刻,原树中颜色相同的点的集合一定是一条链, 即上面这种状态,而这种结构是 ...