NOIP 2018 原题重做

NOIP 2018 原题重做

DAY 1

记忆尤为深刻的一场考试

T1-铺设道路(road)

算法 1(标准做法)

标准Codeforces Div2B难度。
把原题想成是用最少的 1 × D ( ∀ D ∈ [ 1 , + ∞ ) ) 1\times D(\forall D\in[1,+∞)) 1×D(D[1,+))的水平木板覆盖完整个直方图。
考虑现在铺第 i i i个水平位置,那么如果上一个水平位置在直方图内,即可直接将木板延长一次。
因此总的答案就是 ∑ i = 1 n max ⁡ ( h i − h i − 1 , 0 ) \sum^n_{i=1}\max(h_i-h_{i-1},0) i=1nmax(hihi1,0)

算法 2(笛卡尔树)

笛卡尔树模板题,答案就是笛卡尔树的带权 s i z siz siz

算法 3(线段树)

无脑找最小值然后区间减,分治直接做即可。
复杂度最极端是即为直方图表现为 1 … n 1\dots n 1n的情况。
此时复杂度为 ∑ i = 1 n log ⁡ i = log ⁡ i ! \sum^n_{i=1}\log_i=\log i! i=1nlogi=logi!
随便放缩一下就可以得到它上限为 O ( n log ⁡ n ) O(n\log n) O(nlogn)
然而我们也可以用斯特林公式证明 O ( log ⁡ n ! ) = O ( n log ⁡ n ) O(\log n!)=O(n\log n) O(logn!)=O(nlogn)

T2-货币系统(money)

算法 1(标准做法)

显然答案是原货币系统的一个子集,那么我们需要删去一些面额。
我们被删去的面额显然满足它能用较小的面额的货币表示出来。
因此按货币从小到大完全背包即可。

算法 1 plus(拟阵)

其实原问题是一个很经典的拟阵形式,我们只需要证明它是一个拟阵我们就能完全严谨的证明算法1的结论了。
证明如下:

算法 2(同余最短路)

虽然复杂度不优秀,但是思路挺巧妙的。
首先将货币系统 a a a按面值排序。
我们建 a 1 a_1 a1个点分别表示 m o d    a i = k \mod a_i=k modai=k的点。
对于每个 a i ( i > 1 ) a_i(i>1) ai(i>1),连一条 x x x ( x + a i ) m o d    a 1 (x+a_i)\mod a_1 (x+ai)moda1,权值 a i a_i ai的有向边。
对这个图求出源点为 0 0 0到每个点的最短路 d i d_i di
这个 d i d_i di的含义其实就是货币系统 a a a能表示的最小的 k ( k   m o d   a 1 = i ) k(k\bmod a_1=i) k(kmoda1=i)
容易得到满足条件的货币系统的 d i d_i di a a a货币系统的 d i d_i di一致。
因此我们只需要找原图的一个边数种类最小的联通子图即可。
看起来比较困难,其实我们只需要做最短路时尽量保留较小的边即可。

算法 3(生成函数)

显然有一个做法:
F ( x ) = ∏ i = 1 n G i ( x ) F(x)=\prod^n_{i=1}G_i(x) F(x)=i=1nGi(x)
G i ( x ) = ∑ j = 0 + ∞ x v i ⋅ j G_i(x)=\sum^{+∞}_{j=0}x^{v_i·j} Gi(x)=j=0+xvij
复杂度: O ( T n M log ⁡ M ) O(TnM\log M) O(TnMlogM)
然而NTT常数很大会T。
考虑换底,然后化简:
F ( x ) = e ∑ i = 1 n ln ⁡ G i ( x ) = e − ln ⁡ ( 1 − x v j ) F(x)=e^{\sum^n_{i=1}\ln G_i(x)}=e^{-\ln(1-x^{v_j})} F(x)=ei=1nlnGi(x)=eln(1xvj)
e e e上面的然后求导再积分回来:
− ∫ ln ⁡ ′ ( 1 − x v j ) d ( 1 − x v j ) = ∫ v j x v j − 1 1 1 − x v j d x = ∫ v j ∑ i = 0 + ∞ x v j ( i + 1 ) − 1 d x ( 等 比 数 列 公 式 ) = ∑ i = 0 + ∞ x ( i + 1 ) v j ( i + 1 ) = ∑ i = 1 + ∞ x i v j i -\int \ln'(1-x^{v_j}) \mathrm{d}(1-x^{v_j}) \\=\int v_jx^{v_j-1}\frac{1}{1-x^{v_j}} \mathrm{d}x \\=\int v_j\sum^{+∞}_{i=0}x^{v_j(i+1)-1}\mathrm{d}x(等比数列公式) \\=\sum^{+∞}_{i=0}\frac{x^{(i+1)v_j}}{(i+1)} \\=\sum^{+∞}_{i=1}\frac{x^{iv_j}}{i} ln(1xvj)d(1xvj)=vjxvj11xvj1dx=vji=0+xvj(i+1)1dx()=i=0+(i+1)x(i+1)vj=i=1+ixivj

H ( x ) = ∑ i = 1 + ∞ x i v j i H(x)=\sum^{+∞}_{i=1}\frac{x^{iv_j}}{i} H(x)=i=1+ixivj,答案即为 e H ( x ) e^{H(x)} eH(x)中能被表示的方案数为 0 0 0的数的个数。
求出 H ( x ) H(x) H(x)复杂度是调和级数 O ( M log ⁡ M ) O(M\log M) O(MlogM)的, e x p exp exp也是 O ( M log ⁡ M ) O(M\log M) O(MlogM)的。
因此复杂度: O ( T M log ⁡ M ) O(TM\log M) O(TMlogM)
然而它还是过不了。

T3-赛道修建(track)

算法 1(标准做法)

显然对答案进行二分,这样我们就转化为了求最多的划分链个数。
我们尝试用DFS的思路求解。对于一个节点,显然它的每个儿子都至多有一条未处理完的顶部为这个儿子的链。对于当前层,要么我们选出两条链连在一起,要么这条链成为当前点的未处理链。
显然我们可以在里面再套一个二分或者vector来做。
然而当时我不敢写二分套二分写了个双指针挂成80。

算法 2()

DAY 2

T1-旅行(travel)

T2-填数游戏(game)

T3-保卫王国(defense)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值