Solution
令
V=maxli。
Lem. 1:将
a 从小到大排序,相邻数异或值的最小值即为
f(a)。
证明
这是经典问题。可以考虑 trie 求最小异或对的过程,或者也可以证明
a<b<c⇒min(a⊕b,b⊕c)≤a⊕c,总之易证。
Lem. 2:对于长度为
n 的序列
a,
f(a)≤n−12maxai。
证明
考虑如果
f(a)≥2k,
maxai 至少为多少。
f(a)≥2k 的必要条件是
⌊2kai⌋ 两两不同,因此
maxai≥(n−1)2k。故
2k≤n−1maxai,得到
f(a)≤n−12maxai。
设
g(k) 为
f(a)>k 的
a 个数,有
∑k=0maxf(a)g(k)=∑af(a)。原因是序列
a 会在
g(0),g(1),⋯,g(f(a)−1) 中计算,总共算了
f(a) 次。
枚举
k,考虑计算
g(k)。设
ci=∑j=1n[lj≥i]。对于一个从大到小排序的序列
b,由于
f(b)>0,
b 中没有相同的数,因此根据经典的有上限排列计数,对应的
a 的个数为
∏i=1n(cbi−i+1)。
设
fi,j 为确定了
b1,b2,⋯,bi 且
bi=j 的情况下,
∏k=1i(cbi−i+1) 的和。转移:
fi,j=(cj−i+1)∑x=jV[j⊕x>k]fi−1,x
DP 的复杂度为
O(nV2),根据 Lem. 2,枚举
k 的复杂度为
O(nV),我们得到了一个
O(V3) 做法。
- 枚举 j⊕x 与 k 最高的不同的位 h,要求 k 这位为 0,令 k′=⌊2hk′⌋,类推 j′,x′。
- 枚举 j′,得到 x′=(k′+1)⊕j′。
- 可以发现 j′=x′,我们通过 j′,x′ 就确定了 j,x 的大小。跳过 x′<j′ 的情况
- j,x 二进制下的低 h 位是任意的,因此将 fi 的 [j′2h,(j′+1)2h) 加上 ∑t=x′2h(x+1)2h−1fi−1,t。
区间加与区间求和可以通过差分与前缀和实现,这样之后将
fi,j 乘上
(cj−i+1) 即可完成转移。
一次转移复杂度为
O(∑i=0log2V2i)=O(V)。因此总复杂度为
O(V2),可以通过。
感谢
irris提出了 Lem. 2,将此题从
O(nV2) 优化到
O(V2)。
闲话:这题叫纯蓝的很大一部分原因是赛前预估这题为蓝题。