25.10.27
CF1982F
一个想法是找一段前缀,满足其最大值小于等于后缀最小值,然后再做一次后缀的,而且要求了选出的前后缀都不将。
尝试做一下,发现前面这个可以双老哥二分出来,后面这个则可以直接维护 \(a_i>a_{i+1}\) 的位置来求。
那直接取较紧的约束就好了,但发现双老哥过不去。
注意到我们可以先满足后面的,这样需要二分的区间是单调的,前缀为例,前缀最值小于后缀最值就可以转化成单点小于一定值。
直接在这上面 lower_bound/upper_bound 即可。
CF1942F
感觉主要影响值的只有最后几个数,拿个计算器摁一下会发现 \(n>6\) 的时候,前面的几乎对后面不造成影响:至多使其加一。
容易想到分块,维护一下每块 \(0\) 进多少出,\(>x\) 时会加一,每次重构一下再求值即可。
太蠢了,有没有强一点的方法?这个信息貌似是一个半群,可以丢到线段树上。
然而要求区间长度 \(>6\),这难不到我们,直接底层分块。
实现时为了方便在开头加了几个 0 保证块都是完整的。
QOJ14139
比较诡异的题,考察 \((i,j)\) 移动到 \(f(i,j)\),注意到这个是单调的(下面的肯定 U 不过上面的,R 同理),从上往下从左往右定序后,如果某处 \(f(i,j)\ge(i,j)\),那就走不上去了,于是我们要求的就是 \(f(i,j)<(i,j)\) 的位置。
而且可以发现一行中 \((i,1)\) 是最容易合法的位置,如果 \(1\) 过了那就都过了。
于是只需考察 \(\sum\limits_{i-u\le j<i}s_j\ge r\) 的位置。
这个就线段树维护一下,二分找出这个 \(i\),再求 \(1\sim i-1\) 的和。
CF1870G
容易想到二分答案,然后意识到根本无需二分,因为答案变化次数是 \(\mathcal{O}(n)\) 的,尝试后失败的次数也是 \(\mathcal{O}(n)\) 的。
check 答案能否为 \(p\),正着推需要知道后面还要多拼几个进来,于是考虑倒着扫,记录当前多出来的元素(可以直接视作 0)个数 \(cnt\) 和需要多少套前面的元素 \(need\)。
如果发现某一位 \(c_i<need\),那么就需要拼 \(need-c_i\) 个 \(i\) 出来,于是 \(need\gets need-c_i\),反之就是多了些元素,\(cnt\gets c_i-need\)。
最后在 \(0\) 这一位上检验即可,现在尝试加速此过程。
看着很没说法啊,两个操作都不怎么能合并,但是我们也拿不出别的视角了。
考虑操作一我们增加了大量 \(need\),这意味着我们随便加几次就可能无解了!
而且加的总量是 \(\mathcal{O}(n)\) 的,每次加的个数是不同的……那只有根号次操作!
直接用线段树把第二类跳一段,然后暴力做第一类,可以做到 \(\mathcal{O}(n\sqrt{n}\log n)\)。
精细实现,在跳第二类时顺带进行处理(\(\min>need\) 就跳过,无解则返回,否则暴力做),可以分析到 \(\mathcal{O}(n\sqrt{n})\)。
CF1500E
比较烦的题,首先容易发现答案是求若干区间 \([L_i,R_i)\) 并集,其中 \(L_i\) 是排序后前缀和,\(R_i\) 同理。
观察一下,发现区间的分布比较巧妙,前面一段无交,中间一段相邻两个相连,而最后一段又是无交。
为什么呢?因为 \(L_i,R_i\) 是排序后的前后缀和,凸性相反!
因此可以证出一定在前一半和后一半各有一个分界,满足一侧是相邻两区间有交,另一侧无交。
直接将这个分界点记为 \(l,r\),然后答案就长成 \(\sum\limits_{i<l}(R_i-L_i)+(R_r-L_l)+\sum\limits_{i>r}(R_i-L_i)\)。
这个式子能做吗?首先 \(l,r\) 是可以二分出来的,把序列丢进权值线段树即可。
然后是前后缀这一块,稍微化一下就是 \(\sum\limits_{j\le i<l}(a_j-a'_j)=\sum\limits_{j}\sum\limits_{j\le i<l}(a_j-a'_j)\),已经能丢线段树了。
但现在就丢不是很蠢吗?明明还能拆啊,\(\sum\limits_{j}(a_j-a'_j)(l-j)\),也就是维护一下 \(\sum a_j,\sum a_jj\) 这样的东西即可(\(a'_j\) 可以换到 \(a_{n-j+1}\) 上一起弄)。
哎写都写了。另外记得动态开点会被卡常需要离散化,也就是别写动态开点线段树。

浙公网安备 33010602011771号