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

orz

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

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


Description

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

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

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

给定 nn,求 i=0n1Aif(i)\sum_{i=0}^{n-1}A_i\cdot f(i)


Solution

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

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

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

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

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

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

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

An=Popcount(n)mod2A_n=\text{Popcount}(n)\bmod2

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

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

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

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

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


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

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

i=0n1Aif(i)=i=0n1(1(1)P(i)2f(i))=12(i=0n1(f(i)(1)P(i)f(i)))=12(i=0n1f(i)i=0n1(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=0n1(1)P(i)f(i)\sum_{i=0}^{n-1}(-1)^{\text{P}(i)}\cdot f(i)

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

i=0n1(1)P(i)r=0k1arir\sum_{i=0}^{n-1}(-1)^{\text{P}(i)} \sum_{r=0}^{k-1}a_{r}i^{r}

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

r=0k1ari=0n1(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=0n1(1)P(i)ir\sum_{i=0}^{n-1}(-1)^{\text{P}(i)}i^{r}

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


现在我们写出 nn 的二进制表示,是一长串 1100

然后我们从后往前,一个一个地把 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+2514=29+2514=2^9+2 嘛qwq)

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

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

把求和换成从 00 开始:

i=02t1(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,这里的 uutt 就依次是:

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 的个数就是 uuii 各自的二进制表示中 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=02t1(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=02t1(1)P(i)j=0rCrjurjij(-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=0rCrjurji=02t1(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=02t1(1)P(i)ij\sum_{i=0}^{2^t-1}(-1)^{\text{P}(i)}i^j

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


如果我们记

Sum(u,t,r)=i=uu+2t1(1)P(i)ir=i=02t1(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=02t1(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!

也就是说,如果我们知道了对于所有 0jr0\le j\le rSum(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=02t1(1)P(i)ij=i=02t11(1)P(i)ij+i=2t12t1(1)P(i)ij=i=02t11(1)P(i)ij+i=02t11(1)P(i+2t1)(i+2t1)j=Sum(0,t1,j)+Sum(2t1,t1,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,t1,j)\text{Sum}(0,t-1,j)Sum(2t1,t1,j)\text{Sum}(2^{t-1},t-1,j) 来推出 Sum(0,t,j)\text{Sum}(0,t,j)

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


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

i=02t11(1)P(i)ij+i=02t11(1)P(i+2t1)(i+2t1)j=Sum(0,t1,j)+(1)P(2t1)i=02t11(1)P(i)(i+2t1)j=Sum(0,t1,j)i=02t11(1)P(i)(i+2t1)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=02t11(1)P(i)(i+2t1)j\sum_{i=0}^{2^{t-1}-1}(-1)^{\text{P}(i)}(i+2^{t-1})^j

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

i=02t11(1)P(i)(i+2t1)j=i=02t11(1)P(i)s=0jCjs(2t1)jsis=s=0jCjs(2t1)jsi=02t11(1)P(i)is=s=0jCjs(2t1)jsSum(0,t1,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,t1,j)s=0jCjs(2t1)jsSum(0,t1,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^jt>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+1jxj\le x

j<xj<x,则由归纳:

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

s=0jCjs(2x)jsSum(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)jsSum(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)jsSum(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(log2n+k3)O(\log_2n+k^3)。足以通过本题。