CF817D Imbalanced Array 题解
本文迁移自洛谷原文。
实质上这题可以用4棵不同的树状数组莽过去
大致思路其他的题解已经讲的很清楚了,这里就讲讲树状数组的不同写法和作用。
比如这道题,我写的第1、2、3、4棵线段树,作用分别是:
1,求左端后缀最大值
2,求右端后缀最小值
3,求左端前缀最大值
4,求右端前缀最小值
如果是要处理前缀的话,我们的 add 函数 和 ask 函数 应该这么写:
1 | inline void add(int x,int d){for(;x<mxn;x+=x&-x)val[x]=max(val[x],d);} //add 往后 让后面的数在ask时能够处理到它 |
反之,如果是处理后缀的话:
1 | inline void add(int x,int d){for(;x;x-=x&-x)val[x]=max(val[x],d);}//add往前 |
此外,这题还有个小问题,样例以就很好的体现了:在两个数相同的时候,且它们都可以作为最小/大值,那么,他们的贡献就会被多次计算。
其实没有太大的关系,因为我们可以钦定如果两个数相同,前面的数大于后面的数,就可以处理掉这种情况了。实现的话就是在 ask 左端时 ask
Code:
1 | #include<bits/stdc++.h> |
CF615C Running Track 题解
本文迁移自洛谷原文。
首先我们可以先贪心的想:
假设我们已经匹配到了
可以感性证明:如果不用
如果暴力地枚举复杂度会达到
但如果对于
ps. 我写的这个字符串匹配实质上是
code:
1 | using namespace std; |
CF256E Lucky Arrays 题解
本文迁移自洛谷原文。
这里是全网唯一一份分块的题解(也可能是唯一一份分块卡过去的做法)。
现将这
令
处理更新的代码:
1 | inline void go(){ |
然后,查询时有些复杂:
首先,单独处理好整个数列的第一个块(因为
然后,对于接下来的每个块,考虑与上一个块的末尾相接。
先处理好每个块的块首的答案,然后利用
注意要时时刻刻取模。
这样,分块的做法就写好了。
不过,如果你只做到了这儿,你只会想绝大多数分块一样TLE 11
一些优化:
对于查询时的处理,将
展开成 来节省常数 尽量的去掉大括号
register inline
快读快输,火车头
快的大小是信仰数
srand(‘xhztxdy’)使用 C++14 来替代 C++11
痛苦的心路历程(在 mashups 不断测试):

整体代码:
1 |
|
加上信仰火车头是6kb
所以6kb干了2kb的活
P7238 迷失森林 题解
本文迁移自洛谷原文。
这里是验题人的思路(不同于官方题解)
将所有的树都缩成一个点。
对于第
叶子节点要特判。
尤其要特判当1号节点为叶子(只有一条出边)时的情况。
最后对新图求直径即可。
Code:
1 | #include<bits/stdc++.h> |
P5902 [IOI 2009] Salesman 题解
本文迁移自洛谷原文。
考虑dp。
令
1.最朴素的dp
循环
复杂度:
2.分离常项
假设现在是
1.
dp[i]=max(dp[j]+U*(place[i]-place[j]))+val[i]
有
$dp_j+U*(place_i-place_j)=dp_j-Uplace_j+Uplace_i$
所以
dp[i]=max(dp[j]-U*place[j])+val[i]+U*place[i]
用线段树/树状数组维护即可。
2.
同理。
时间复杂度:
3.日期相同的情况
贪心可得一定是从一个点直着走到另一个点,中间不会回头。
这里单独弄一个dp。
预处理出不考虑相同日期时每一个点的dp值,然后从左往右、从右往左贪心的递推即可。类似最大子段和。
Code:
1 | #include<bits/stdc++.h> |
CF1408C Discrete Acceleration 题解
本文迁移自洛谷原文。
一道较为简单的双指针
每次维护左边的人走到那个旗子,右边的人走到那个旗子,慢慢向中间不断更新靠拢即可。
1 | #include<bits/stdc++.h> |
CF1408D Searchlights 题解
本文迁移自洛谷原文。
考虑dp。
令
对于数据预处理完后,倒着去一边取
1 | #include<bits/stdc++.h> |
CF1408E Avoid Rainbow Cycles 题解
本文迁移自洛谷原文。
考虑构图。
对于集合
由于题目要求说是无还,所以对这张新图跑最大生成树即可。(不是树必然有环)
最大生成树就是将最小生成树 Kruskal 中每次取出边权最小的边改为最大的边即可,
Code:
1 | #include<bits/stdc++.h> |
CF1419E Decryption 题解
本文迁移自洛谷原文。
人菜,只会打暴力
虽然是用小号, 但还是div2里第一个AC的
由于每操作一次就相当于将两个不互质的数变得互质,所以我们的目标是找到一种排列使得相邻两个数不互质的数量尽可能的少。
考虑分解质因数。将由相同质因数的放在一起,留下一个做为连接这个质因数与下一个质因数的桥梁。
暴力即可。
1 | #include<bits/stdc++.h> |