6508. 【GDOI2020模拟03.11】我的朋友们

7 篇文章 0 订阅
3 篇文章 0 订阅

题目

有一个长度为 n n n的数列 a i a_i ai,一开始将数列的前 L L L个丢入队列中。
一次操作是对于队列中的每个数 a i a_i ai,有 a i a_i ai的几率有 1 1 1的贡献。设贡献和为 x x x
然后将队列中前 x x x个弹出去,再从数列中接着 x x x个。
如果数列中的数取完了,操作停止。
问期望进行多少次操作。


思考历程

一开始就看错了题意,于是这就变成的了一道神仙题。
只想到了 a i a_i ai相等的情况。
由于时间不够,写出来之后调都不调就交了。
结果自然是爆0。
(话说我在写这个东西的时候没有用分治NTT……不知道是我的方法错了,还是确实能不用分治NTT……)


正解

f i f_i fi为当前队列中的数在 [ i , i + L ) [i,i+L) [i,i+L)中的期望。
转移十分显然,这里就不写了。
直接暴力转移肯定不能过,接下来就是在这个东西的基础上优化。

把整个序列倒过来做, f i f_i fi就变成了当前队列中的数在 ( i − L , i ) (i-L,i) (iL,i)中的期望。
P i = ∏ j = i − L + 1 i ( 1 − a j + a j x ) P_i=\prod_{j=i-L+1}^i (1-a_j+a_jx) Pi=j=iL+1i(1aj+ajx)
随便推一推得:
f i = 1 + ∑ j = 1 L f i − j [ x j ] P i 1 − [ x 0 ] P [ i ] f_i=\frac{1+\sum_{j=1}^Lf_{i-j}[x^j]P_i}{1-[x^0]P[i]} fi=1[x0]P[i]1+j=1Lfij[xj]Pi
接下来问题是处理 ∑ j = 1 L f i − j [ x j ] P i \sum_{j=1}^Lf_{i-j}[x^j]P_i j=1Lfij[xj]Pi,其它的都很好办。
F i = ∑ j = L i f j x j F_i=\sum_{j=L}^if_jx^j Fi=j=Lifjxj
于是 ∑ j = 1 L f i − j [ x j ] P i = [ x i ] ( F i − 1 P i ) \sum_{j=1}^Lf_{i-j}[x^j]P_i=[x^i](F_{i-1}P_i) j=1Lfij[xj]Pi=[xi](Fi1Pi)
这下就好看很多了。

考虑分治NTT。假如现在要计算区间 [ l , r ] [l,r] [l,r]的答案。
对于每个 i ∈ [ l , r ] i\in[l,r] i[l,r],我们把 P i P_i Pi的公因数提取出来,就是 ∏ j = r − L + 1 l ( 1 − a j + a j x ) \prod_{j=r-L+1}^l(1-a_j+a_jx) j=rL+1l(1aj+ajx)
F l , r ′ = F l − 1 ∏ j = r − L + 1 l ( 1 − a j + a j x ) F_{l,r}^{'}=F_{l-1}\prod_{j=r-L+1}^l(1-a_j+a_jx) Fl,r=Fl1j=rL+1l(1aj+ajx),这就是前面 [ 1 , l − 1 ] [1,l-1] [1,l1]区间对每一个 i ∈ [ l , r ] i\in [l,r] i[l,r]共有的贡献,可以一起算。
[ x i ] F i , i ′ [x^i]F_{i,i}^{'} [xi]Fi,i就是对 f i f_i fi的贡献。
考虑如何从 F l , r ′ F_{l,r}^{'} Fl,r转移至 F l , m i d ′ F_{l,mid}^{'} Fl,mid F m i d + 1 , r ′ F_{mid+1,r}^{'} Fmid+1,r
F l , m i d ′ = F l − 1 ∏ j = m i d − L + 1 l ( 1 − a j + a j x ) = F l , r ′ ∏ j = m i d − L + 1 r − L ( 1 − a j + a j x ) F_{l,mid}^{'}=F_{l-1}\prod_{j=mid-L+1}^l(1-a_j+a_jx)\\=F_{l,r}^{'}\prod_{j=mid-L+1}^{r-L}(1-a_j+a_jx) Fl,mid=Fl1j=midL+1l(1aj+ajx)=Fl,rj=midL+1rL(1aj+ajx)
F m i d + 1 , r ′ = F m i d ∏ j = r − L + 1 m i d + 1 ( 1 − a j + a j x ) = F l , r ′ ∏ j = l + 1 m i d + 1 ( 1 − a j + a j x ) + ( ∑ i = l m i d f i x i ) ∏ j = r − L + 1 m i d + 1 ( 1 − a j + a j x ) F_{mid+1,r}^{'}=F_{mid}\prod_{j=r-L+1}^{mid+1}(1-a_j+a_jx)\\=F_{l,r}^{'}\prod_{j=l+1}^{mid+1}(1-a_j+a_jx)+(\sum_{i=l}^{mid}f_ix^i)\prod_{j=r-L+1}^{mid+1}(1-a_j+a_jx) Fmid+1,r=Fmidj=rL+1mid+1(1aj+ajx)=Fl,rj=l+1mid+1(1aj+ajx)+(i=lmidfixi)j=rL+1mid+1(1aj+ajx)
上面式子中的那堆连乘都是可以用分治NTT预处理的。
看起来这个东西并没有优秀到哪里去啊……

我们想要求的,仅仅是 [ x i ] F i , i ′ [x^i]F_{i,i}^{'} [xi]Fi,i
对于 F l , r ′ F_{l,r}^{'} Fl,r,如果它一直转移到了叶子节点,那么乘上的多项式的次数是 O ( r − l ) O(r-l) O(rl)级别的。
我们最终只要对 i ∈ [ l , r ] i\in [l,r] i[l,r]的所有 i i i有用的项,这意味着有些次数很小的项,他们次数增高 O ( r − l ) O(r-l) O(rl)之后依然不会对任何 i ∈ [ l , r ] i\in[l,r] i[l,r] i i i产生影响,这个项就是没用的。
对于没用的项,那就可以忽略不计。
所以,只需要存最后 O ( r − l ) O(r-l) O(rl)项就可以了。题解说标程存了最后 2 ( r − l + 1 ) 2(r-l+1) 2(rl+1)项。

于是这题就做完了,时间复杂度 O ( n lg ⁡ 2 n ) O(n \lg^2 n) O(nlg2n)


总结

一个晚上,两个小时思考,再加一个小时写博客整理思路。
这种到现在pty都没有AC的题目,我不知道写出来要多长时间。
就先把题解晾在这里好了……

这题的精髓,除了乱推一波式子以外,我认为是最后的那个保留最后几项的那个操作。
我终于明白了原来分治NTT还能这么搞。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值