首页 > 其他分享 >CF1334F Strange Function 题解

CF1334F Strange Function 题解

时间:2024-09-16 19:12:41浏览次数:1  
标签:Function le 单点 题解 查询 CF1334F 数组 max sim

传送门

定义一个函数 \(f\),输入一个数组 \(a\),输出一个数组 \(b\) 为 \(a\) 的子序列:\(b_1=a_1\),设 \(b_i\) 在 \(a\) 中的位置为 \(pos_i\),则 \(b_i\) 为 \(a_{pos_{i-1}+1}\sim a_n\) 中第一个严格大于 \(b_{i-1}\) 的数。\(n\le 5\times 10^5\),\(|p_i|\le 10^9,1\le a_i,b_i\le n, b_{i-1}<b_i\)。

给定长度 \(n\) 的数组 \(a\) 和数组 \(p\),以及长度 \(m\le n\) 的严格递增的数组 \(b\)。删除 \(a_i\) 需要 \(p_i\) 的代价,问删除一些数使 \(a\rightarrow a'\),\(f(a')=b\) 的最小代价是多少。


转化问题,变成保留一些数最大代价是多少。

注意到 \(f\) 的定义是严格递增,所以余下的数必然两两不同,显然用 map 可以 \(O(n\log n)\) 预处理出 \(a_i\) 在 \(b\) 中哪个位置出现过。

一个简单的思路是 \(f_i\) 表示考虑 \(a\) 的前 \(i\) 个数,必须保留 \(a_i\)(如果 \(a_i\not\in b\) 则 \(f_i=-\infty\)),能保留的数的最大价值之和。
设 \(a_i=b_j\)。

写出转移方程:$$f_i=\max_{0\le k\le i-1,a_k=b_{j-1}} (f_k+\sum_{t=k+1}^{i-1}[a_t\le a_k][p_t>0]p_t+p_i)$$

直接硬来是 \(O(n^3)\) 的,考虑优化。优化 DP 的一个重要思路是动态维护每个决策点的值。

令 \(g_k=f_k+\sum_{t=k+1}^{i-1}[a_t\le a_k][p_t>0]p_t+p_i\),尝试随着在 \(i\) 增大的过程中维护 \(g_k\)(\(k=0\sim i-1\))。但就算成功维护了 \(g\),算法仍然是 \(O(n^2)\) 的不能接受。还需要再套一层。
于是引入一个 \(G_v=\max_{0\le k<i,a_k=v}\{g_k\}\),则有 \(f_i=G_{b_j-1}+p_i\)。我们尝试动态维护 \(G_x\)(\(x=0\sim n\))。

因为 \(G\) 的变化是基于 \(g\) 的变化,我们先研究 \(g\) 是如何变化的。

在 \(i\rightarrow i+1\) 的时刻,可能有两种更新:一种是 \(g_{0\sim i-1}\) 的更新,一种是新增了 \(g_i\)。
对于旧 \(g_k\) 的改变,都增加了 \([a_i\le a_k][p_i>0]p_i\)。对于 \(p_i\le 0\) 的情况,直接略去,因为不会产生任何贡献;当 \(p_i>0\),每个 \(g_k\) 增加 \([a_k\ge a_i]\cdot p_i\)。

对于新增的 \(g_i\),容易发现 \(g_i=f_i\)。

那么 \(G_x\) 的变化是怎么样的呢?对于旧 \(g_k\) 的改变,容易发现对于 \(v\ge a_i\),\(G_v\) 增加 \(p_i\);对于新增的 \(g_i\),有 \(G_{a_i}=\max(G_{a_i},f_i)\)。

当我们询问 \(G\),只需要查询 \(G_{v}\) 一个位置的值即可。

所以 \(G\) 需要支持:后缀加法、单点取 \(\max\)、单点查询。

直接线段树当然可以,但是有些大材小用了。单点 \(\max\) 可以拆成一次查询和两次后缀加法。再把数组 reverse 一下,就变成前缀加法和单点查询,使用 BIT 可以完成。

标签:Function,le,单点,题解,查询,CF1334F,数组,max,sim
From: https://www.cnblogs.com/FLY-lai/p/18416508

相关文章

  • 嘉应学院第一届新生娱乐赛第一场题解
    A一道简单的语法题,直接输出"hellonowcoder"即可。代码#include<stdio.h>intmain(){printf("hellonowcoder");}B也是一道语法题,考察分支结构。根据题意进行判断输出即可。代码#include<stdio.h>intmain(){inta,b;scanf("%d%d",&a,&......
  • [ARC096E] Everything on It 题解
    题目链接点击打开链接题目解法肯定考虑容斥钦定有\(a\)个数出现\(0\)次,有\(b\)个数出现恰好\(1\)次,其他\(n-a-b\)个数随便,容斥系数为\((-1)^{a+b}\)先给出方案数的表达式:\(\sum\limits_{a=0}^n\sum\limits_{b=0}^{n-a}(-1)^{a+b}2^{2^{n-a-b}}\binom{n}{a}\binom{......
  • 图:310.最小高度数, 题解
    310.最小高度树-力扣(LeetCode)参考题解:算法逻辑:算法的核心思路是逐层剪去叶子节点,直到剩下的节点是最小高度树的根。示例:假设有如下的树结构:0/\12/\34初始时,叶子节点是1、3和4,剪掉这些叶子节点后,树变成:0\2再次剪掉......
  • 【洛谷 P1216】[USACO1.5] [IOI1994]数字三角形 Number Triangles 题解(动态规划)
    [USACO1.5][IOI1994]数字三角形NumberTriangles题目描述观察下面的数字金字塔。写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。在上面的样例中,从的路径产生了最大权值。输入格式第一个行一个正整数......
  • 题解:P9938 [USACO21OPEN] Acowdemia II B
    首先根据每篇出版物构建一个资历比较矩阵\(g\),其中\(g_{a,b}=1\)表示研究员\(a\)比\(b\)资历更高。遍历每篇出版物,识别出第一个降序的名字,然后假定该名字之后的所有研究员资历都比当前名字对应的研究员资历高即可。代码:#include<bits/stdc++.h>usingnamespacestd;......
  • 题解:P9951 [USACO20FEB] Swapity Swap B
    奶牛的排列经过\(x\)次后会回到原来的位置,理解以下:\([a_1,a_2]\)的牛翻转两次就会回到原来的位置,\([b_1,b_2]\)的牛翻转两次也会回到原来的位置,所以原来奶牛的排列经过一定次数的旋转后一定会回到原来位置。我们只要先模拟得出多少次后第\(i\)位的奶牛会回到原来的位置,然后......
  • 题解:P9953 [USACO20OPEN] Social Distancing II B
    解决思路:根据奶牛的位置对数组进行排序。计算相邻健康奶牛和感染奶牛之间的最小距离。这个距离值减一用来估计感染传播的半径。(确保了感染奶牛之间的距离在当前半径下不会导致传播给其他健康奶牛。)遍历排序后的奶牛列表,找到每一段连续感染奶牛的区域,并计算这些区域中可能需要的......
  • 区间检测题解
    记录\(pre_i\)为\(a_i\)上一次出现的位置。每一次求\([L,R]\)范围内是否有相同的数即\(pre_L\)到\(pre_R\)中的最大值是否小于\(L\)。注意到\(pre_1\)到\(pre_{L-1}\)中最大数一定小于\(L\),所以求\([L,R]\)范围内是否有相同的数即\(pre_1\)到\(pre_R\)中的......
  • 题解:P9957 [USACO20DEC] Stuck in a Rut B
    由于\(x,y\leq10^9\),我们无法模拟每个时间段。因此,我们需要尝试判断两头牛何时会相交。一个重要的观察是,牛不能后退,所以两头牛发生碰撞的唯一方式是\(n[x]>e[x]\)且\(n[y]<e[y]\)。可以按牛的起始坐标进行排序,然后模拟这些碰撞。代码:#include<bits/stdc++.h>using......
  • 题解:P3113 [USACO14DEC] Marathon G
    用线段树维护子路径的长度和这条子路径上删除一个点能够减少的最大距离。那么,修改就修改线段树上对应位置的值,查询就求这一段子路径的距离和子路径上删除一个点能够减少的最大距离,两者相减即可得到答案。代码:#include<bits/stdc++.h>usingnamespacestd;typedefpair<int,in......