NOIP 2018 原题重做
DAY 1
记忆尤为深刻的一场考试
T1-铺设道路(road)
算法 1(标准做法)
标准Codeforces Div2B难度。
把原题想成是用最少的1×D(∀D∈[1,+∞))的水平木板覆盖完整个直方图。
考虑现在铺第i个水平位置,那么如果上一个水平位置在直方图内,即可直接将木板延长一次。
因此总的答案就是∑i=1nmax(hi−hi−1,0)
算法 2(笛卡尔树)
笛卡尔树模板题,答案就是笛卡尔树的带权siz。
算法 3(线段树)
无脑找最小值然后区间减,分治直接做即可。
复杂度最极端是即为直方图表现为1…n的情况。
此时复杂度为∑i=1nlogi=logi!。
随便放缩一下就可以得到它上限为O(nlogn)。
然而我们也可以用斯特林公式证明O(logn!)=O(nlogn)。
T2-货币系统(money)
算法 1(标准做法)
显然答案是原货币系统的一个子集,那么我们需要删去一些面额。
我们被删去的面额显然满足它能用较小的面额的货币表示出来。
因此按货币从小到大完全背包即可。
算法 1 plus(拟阵)
其实原问题是一个很经典的拟阵形式,我们只需要证明它是一个拟阵我们就能完全严谨的证明算法1的结论了。
证明如下:

算法 2(同余最短路)
虽然复杂度不优秀,但是思路挺巧妙的。
首先将货币系统a按面值排序。
我们建a1个点分别表示modai=k的点。
对于每个ai(i>1),连一条x到(x+ai)moda1,权值ai的有向边。
对这个图求出源点为0到每个点的最短路di。
这个di的含义其实就是货币系统a能表示的最小的k(kmoda1=i)。
容易得到满足条件的货币系统的di与a货币系统的di一致。
因此我们只需要找原图的一个边数种类最小的联通子图即可。
看起来比较困难,其实我们只需要做最短路时尽量保留较小的边即可。
算法 3(生成函数)
显然有一个做法:
F(x)=i=1∏nGi(x)
Gi(x)=j=0∑+∞xvi⋅j
复杂度:O(TnMlogM)。
然而NTT常数很大会T。
考虑换底,然后化简:
F(x)=e∑i=1nlnGi(x)=e−ln(1−xvj)
将e上面的然后求导再积分回来:
−∫ln′(1−xvj)d(1−xvj)=∫vjxvj−11−xvj1dx=∫vji=0∑+∞xvj(i+1)−1dx(等比数列公式)=i=0∑+∞(i+1)x(i+1)vj=i=1∑+∞ixivj
设H(x)=∑i=1+∞ixivj,答案即为eH(x)中能被表示的方案数为0的数的个数。
求出H(x)复杂度是调和级数O(MlogM)的,exp也是O(MlogM)的。
因此复杂度:O(TMlogM)。
然而它还是过不了。
T3-赛道修建(track)
算法 1(标准做法)
显然对答案进行二分,这样我们就转化为了求最多的划分链个数。
我们尝试用DFS的思路求解。对于一个节点,显然它的每个儿子都至多有一条未处理完的顶部为这个儿子的链。对于当前层,要么我们选出两条链连在一起,要么这条链成为当前点的未处理链。
显然我们可以在里面再套一个二分或者vector来做。
然而当时我不敢写二分套二分写了个双指针挂成80。
算法 2()
DAY 2
T1-旅行(travel)
T2-填数游戏(game)
T3-保卫王国(defense)