题解 【P7468 [NOI Online 2021 提高组] 愤怒的小 N】

orz

场上推了一半不会了qwq,还是太菜啦/dk

由于云浅太菜了,所以写的可能会通俗一点qwq(


Description

有一个可爱的数列 {An}\{A_n\},满足:

A0=0A_0=0
An=1−An−2mA_{n}=1-A_{n-2^{m}},其中 mm 是使得 2m≤n2^{m}\le n 的最大的正整数。

再给你一个可爱的 k−1k-1 次多项式 f(x)=∑i=0k−1aixif(x)=\sum_{i=0}^{k-1}a_ix^{i}。

给定 nn,求 ∑i=0n−1Ai⋅f(i)\sum_{i=0}^{n-1}A_i\cdot f(i)。


Solution

第一步肯定要处理 {An}\{A_n\} ,毕竟这个数列太神奇了,不搞一下都没法做>_<

首先看一下数列 {An}\{A_n\} 到底是什么东西。

仔细观察这个递推式:An=1−An−2mA_{n}=1-A_{n-2^{m}}。

我们发现,如果把 nn 的二进制表达写出来,那么减去这个 2m2^m ,就相当于把 nn 最高位上的那个 11 去掉!

毕竟,2m2^{m} 在二进制下总是一个 11 后面跟一长串 00,而且这还是使得 2m≤n2^{m}\le n 的最大的正整数嘛,那就只能是最高位和 nn 一样都是 11,然后后面全是 00 qwq。

于是 An−2mA_{n-2^{m}} 到 AnA_n 就相当于在前头加了个 11,那就相当于把 AnA_n 的二进制表达中奇偶性翻转。

再结合 A0=0A_0=0,就有:

An=Popcount(n) mod 2A_n=\text{Popcount}(n)\bmod2

其中 Popcount(n)\text{Popcount}(n) 表示 nn 的二进制表达中的 11 个数。方便起见,下面统一简记为 P(n)\text{P}(n)。

但是这个  mod 2\bmod 2 让我们很难受啊>_<

用一个常见的技巧,把  mod 2\bmod 2 搞掉:

An=P(n) mod 2=1−(−1)P(n)2 A_n=\text{P}(n)\bmod2=\dfrac{1-(-1)^{\text{P}(n)}}{2}

于是那我们就成功搞掉了 AnA_n,把它变得更可爱啦(๑ `▽´๑)


回到要求出来的这个式子。

把我们之前推出来的 AnA_n 带进去化简一通:

∑i=0n−1Ai⋅f(i)=∑i=0n−1(1−(−1)P(i)2⋅f(i))=12(∑i=0n−1(f(i)−(−1)P(i)⋅f(i)))=12(∑i=0n−1f(i)−∑i=0n−1(−1)P(i)⋅f(i))\begin{aligned} \sum_{i=0}^{n-1}A_i\cdot f(i)&=\sum_{i=0}^{n-1}\left(\dfrac{1-(-1)^{\text{P}(i)}}{2}\cdot f(i)\right)\\ &=\dfrac{1}{2}\left(\sum_{i=0}^{n-1}\left(f(i)-(-1)^{\text{P}(i)}\cdot f(i)\right)\right)\\ &=\dfrac{1}{2}\left(\sum_{i=0}^{n-1}f(i)-\sum_{i=0}^{n-1}(-1)^{\text{P}(i)}\cdot f(i)\right) \end{aligned}

诶,前面就是一个 f(x)f(x) 的前缀和嘛!

那就可以直接拉格朗日插值,O(k2)O(k^2) 求出前缀和的表达式,然后带进去算出这部分qwq。

现在主要看后面这部分:

∑i=0n−1(−1)P(i)⋅f(i)\sum_{i=0}^{n-1}(-1)^{\text{P}(i)}\cdot f(i)

貌似这种形式没法继续推。把 f(i)f(i) 展开试试:

∑i=0n−1(−1)P(i)∑r=0k−1arir\sum_{i=0}^{n-1}(-1)^{\text{P}(i)} \sum_{r=0}^{k-1}a_{r}i^{r}

交换一下求和顺序(其实就是提取公因式):

∑r=0k−1ar∑i=0n−1(−1)P(i)ir\sum_{r=0}^{k-1}a_r\sum_{i=0}^{n-1}(-1)^{\text{P}(i)}i^{r}

诶,前面的这个系数 ara_r 是很好算的嘛qwq!

那我们现在要求的就是:

∑i=0n−1(−1)P(i)ir\sum_{i=0}^{n-1}(-1)^{\text{P}(i)}i^{r}

然后,我当时就推到这里,推不下去啦>_<


现在我们写出 nn 的二进制表示,是一长串 11 和 00。

然后我们从后往前,一个一个地把 nn 二进制表示中的 11 去掉,去掉之后的数和去掉之前的数构成了一个区间。

这样就把 [0,n)[0,n) 划分成了很多个区间,并且每个区间的长度都是 22 的正整数次幂。

比如随便写一个 n=114=(1110010)2n=114=(1110010)_2,那么就把 [0,n)[0,n) 划分成了:

  • [(1110000)2,(1110010)2)[(1110000)_2,(1110010)_2),即 [112,114)[112,114)
  • [(1100000)2,(1110000)2)[(1100000)_2,(1110000)_2),即 [96,112)[96,112)
  • [(1000000)2,(1100000)2)[(1000000)_2,(1100000)_2),即 [64,96)[64,96)
  • [0,(1000000)2)[0,(1000000)_2),即 [0,64)[0,64)

当然你也可以拿 514=(1000000010)2514=(1000000010)_2 验证一下qwq。

(其实就是 114=26+25+24+2114=2^6+2^5+2^4+2,514=29+2514=2^9+2 嘛qwq)

那么我们考虑一段长度为 2t2^t 的区间 [u,u+2t)[u,u+2^t) 中的和:

∑i=uu+2t−1(−1)P(i)ir\sum_{i=u}^{u+2^t-1}(-1)^{\text{P}(i)}i^{r}

把求和换成从 00 开始:

∑i=02t−1(−1)P(i+u)(i+u)r\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i+u)}(i+u)^{r}

显而易见的一点是,要么 u=0u=0,要么 uu 的最低位上的 11 要比 2t2^t 的最高位上的 11 靠前,即 lowbit(u)>highbit(2t)\text{lowbit}(u)>\text{highbit}(2^t)。

毕竟,我们每一次区间的转换其实就相当于在 uu 的后面的一堆 00 上选一位变成 11 嘛qwq。

比如前面的例子 n=114=(1110010)2n=114=(1110010)_2,这里的 uu 和 tt 就依次是:

u000000010000001100000111000011100102t10000001000001000010/\begin{aligned}u&&0000000 &&1000000&&1100000&&1110000&&1110010\\2^t&&1000000&&100000&&10000&&10&&/\end{aligned}

既然 uu 的最低位上的 11 都比 2t2^t 的最高位上的 11 靠前,那它肯定比 ii 的最高位上的 11 靠前。也就是说,u+iu+i 的二进制表示中,不会发生进位!

那么 u+iu+i 的二进制表示中的 11 的个数就是 uu 和 ii 各自的二进制表示中 11 的个数之和,即:P(u+i)=P(u)+P(i)\text{P}(u+i)=\text{P}(u)+\text{P}(i)。

那么就可以提出来一个 (−1)P(u)(-1)^{\text{P}(u)},把式子变成:

(−1)P(u)⋅∑i=02t−1(−1)P(i)(i+u)r(-1)^{\text{P}(u)}\cdot\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}(i+u)^{r}

再用二项式定理展开 (i+u)r(i+u)^r,得到:

(−1)P(u)⋅∑i=02t−1(−1)P(i)∑j=0rCrjur−jij(-1)^{\text{P}(u)}\cdot\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}\sum_{j=0}^{r}C_{r}^ju^{r-j}i^{j}

再交换求和顺序:

(−1)P(u)⋅∑j=0rCrjur−j∑i=02t−1(−1)P(i)ij(-1)^{\text{P}(u)}\cdot\sum_{j=0}^{r}C_r^ju^{r-j}\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}i^j

仔细观察这个式子的后半部分qwq!

∑i=02t−1(−1)P(i)ij\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}i^j

嘛......这个东西,好像在前面见过?


如果我们记

Sum(u,t,r)=∑i=uu+2t−1(−1)P(i)ir=∑i=02t−1(−1)P(i+u)(i+u)r\text{Sum}(u,t,r)=\sum_{i=u}^{u+2^t-1}(-1)^{\text{P}(i)}i^{r}=\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i+u)}(i+u)^{r}

诶,刚才那个式子的后半部分

∑i=02t−1(−1)P(i)ij\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}i^j

不就是 Sum(0,t,j)\text{Sum}(0,t,j) 嘛qwq!

也就是说,如果我们知道了对于所有 0≤j≤r0\le j\le r 的 Sum(0,t,j)\text{Sum}(0,t,j) 的值,那么就可以在 O(r)O(r) 的时间内算出 Sum(u,t,r)\text{Sum}(u,t,r)。

至于 Sum(0,t,j)\text{Sum}(0,t,j) 的值,那直接变形一下:

Sum(0,t,j)=∑i=02t−1(−1)P(i)ij=∑i=02t−1−1(−1)P(i)ij+∑i=2t−12t−1(−1)P(i)ij=∑i=02t−1−1(−1)P(i)ij+∑i=02t−1−1(−1)P(i+2t−1)(i+2t−1)j=Sum(0,t−1,j)+Sum(2t−1,t−1,j)\begin{aligned} \text{Sum}(0,t,j)&=\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}i^j\\ &=\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}i^j+\sum_{i=2^{t-1}}^{2^t-1}(-1)^{\text{P}(i)}i^j\\ &=\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}i^j+\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i+2^{t-1})}(i+2^{t-1})^j\\ &=\text{Sum}(0,t-1,j)+\text{Sum}(2^{t-1},t-1,j)\\ \end{aligned}

那么我们发现,类似于动态规划,可以用 Sum(0,t−1,j)\text{Sum}(0,t-1,j) 和 Sum(2t−1,t−1,j)\text{Sum}(2^{t-1},t-1,j) 来推出 Sum(0,t,j)\text{Sum}(0,t,j)。

直接硬算的话,由于总共有 O(k+log⁡2n)O(k+\log_2n) 个不同的 xx,而两重的递推又是 O(k2)O(k^2) 的,所以总复杂度为 O(k3+k2log⁡2n)O(k^3+k^2\log_2n),可以获得 60pts60pts。


回到刚才的那个式子,另一方面,它也可以变成:

∑i=02t−1−1(−1)P(i)ij+∑i=02t−1−1(−1)P(i+2t−1)(i+2t−1)j=Sum(0,t−1,j)+(−1)P(2t−1)⋅∑i=02t−1−1(−1)P(i)(i+2t−1)j=Sum(0,t−1,j)−∑i=02t−1−1(−1)P(i)(i+2t−1)j\begin{aligned} &\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}i^j+\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i+2^{t-1})}(i+2^{t-1})^j\\ =&\text{Sum}(0,t-1,j)+(-1)^{\text{P}(2^{t-1})}\cdot \sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}(i+2^{t-1})^j\\ =&\text{Sum}(0,t-1,j)-\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}(i+2^{t-1})^j\\ \end{aligned}

推到这里之后发现有一个和之前形式几乎一模一样的:

∑i=02t−1−1(−1)P(i)(i+2t−1)j\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}(i+2^{t-1})^j

类似之前的操作,用二项式定理展开并交换求和顺序,就得到:

∑i=02t−1−1(−1)P(i)(i+2t−1)j=∑i=02t−1−1(−1)P(i)∑s=0jCjs(2t−1)j−sis=∑s=0jCjs(2t−1)j−s∑i=02t−1−1(−1)P(i)is=∑s=0jCjs(2t−1)j−sSum(0,t−1,s)\begin{aligned} \sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}(i+2^{t-1})^j&=\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}\sum_{s=0}^{j}C_{j}^s\left(2^{t-1}\right)^{j-s}i^{s}\\ &=\sum_{s=0}^{j}C_j^s\left(2^{t-1}\right)^{j-s}\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}i^s\\ &=\sum_{s=0}^jC_j^s\left(2^{t-1}\right)^{j-s}\text{Sum}(0,t-1,s) \end{aligned}

于是就得到另一个递推式:

Sum(0,t,j)=Sum(0,t−1,j)−∑s=0jCjs(2t−1)j−sSum(0,t−1,s)\text{Sum}(0,t,j)=\text{Sum}(0,t-1,j)-\sum_{s=0}^jC_j^s\left(2^{t-1}\right)^{j-s}\text{Sum}(0,t-1,s)

利用这个递推式,可以发现一个结论:若 2t>2j2^{t}>2^j 即 t>jt>j 时,总有:

Sum(0,t,j)=0\text{Sum}(0,t,j)=0

t=0t=0 时显然成立。

若 t=xt=x 时,对于 j<tj<t,均有 Sum(0,x,j)=0 \text{Sum}(0,x,j)=0。

则当 t=x+1t=x+1 时,对于任意的 j<x+1j<x+1 即 j≤xj\le x:

若 j<xj<x,则由归纳:

Sum(0,x,j)=0\text{Sum}(0,x,j)=0

∑s=0jCjs(2x)j−sSum(0,x,s)=0\sum_{s=0}^jC_j^s\left(2^{x}\right)^{j-s}\text{Sum}(0,x,s)=0

那么

Sum(0,x+1,j)=Sum(0,x,j)−∑s=0jCjs(2x)j−sSum(0,x,s)=0\text{Sum}(0,x+1,j)=\text{Sum}(0,x,j)-\sum_{s=0}^jC_j^s\left(2^{x}\right)^{j-s}\text{Sum}(0,x,s)=0

若 j=xj=x,则:

Sum(0,x+1,j)=Sum(0,x,j)−∑s=0jCjs(2x)j−sSum(0,x,s)=Sum(0,x,j)−Sum(0,x,j)=0\begin{aligned} \text{Sum}(0,x+1,j)&=\text{Sum}(0,x,j)-\sum_{s=0}^jC_j^s\left(2^{x}\right)^{j-s}\text{Sum}(0,x,s)\\ &=\text{Sum}(0,x,j)-\text{Sum}(0,x,j)=0 \end{aligned}

于是命题对 t=x+1t=x+1 仍然成立。

因此,若 t>jt>j,则 Sum(0,t,j)=0\text{Sum}(0,t,j)=0。

类似地,我们也可以证明:对于 Sum(x,t,j)\text{Sum}(x,t,j),若 x>2jx>2^j,则同样也有 Sum(x,t,j)=0\text{Sum}(x,t,j)=0。


由上面两个结论,可以发现:实际上真正「有用」的 xx 只有 O(k)O(k) 个。毕竟,如果 xx 太大了,那这个小可爱就是 00 嘛QAQ。

那我们就可以在 O(k3)O(k^3) 的时间内计算后面的东西,再加上前面的东西,总复杂度 O(log⁡2n+k3)O(\log_2n+k^3)。足以通过本题。