0%

第 N+1 次头疼

头晕头痛,耳鸣眼花,什么题都做不出了。

P7468 愤怒的小 N

题意

k1k-1 次多项式 f(x)f(x),求 i=1n[popcount(i)mod2]f(i)\sum_{i=1}^n[\mathrm{popcount}(i)\bmod 2]f(i),对 109+710^9+7 取模。log2n5×105\log_2 n \leq 5\times 10^5k500k \leq 500

题解

log2n\log_2 n 实在是太大了,而这个 popcount(i)mod2\mathrm{popcount}(i)\bmod 2 也就是只统计二进制下有奇数个 11 的数比较烦。如果我们把它变成 1212(1)popcount(i)\dfrac {1}{2}-\dfrac 12(-1)^{\mathrm{popcount}(i)} 的形式分别计算,那么前半部分与 ii 无关,后半部分的形式就变得很好。具体而言:

i=1n[popcount(i)mod2]f(i)=12i=1nf(i)12i=1n(1)popcount(i)f(i)\begin{aligned} &\sum_{i=1}^n[\mathrm{popcount}(i)\bmod 2]f(i)\\ =&\dfrac 12\sum_{i=1}^nf(i)-\dfrac 12\sum_{i=1}^n(-1)^{\mathrm{popcount}(i)}f(i) \end{aligned}

前面一部分拉格朗日插值,容易处理。后半段我们可以枚举 iinn 二进制位的 LCP,那么后面的二进制位就不受限制,前面在 (1)popcount(i)(-1)^{\mathrm{popcount}(i)} 的贡献无非就是一个容易计算的 111-1。记 mx=2xn2xm_x=2^x\left\lfloor\dfrac{n}{2^x}\right\rfloor,也就是 nn 去掉最低 xx 位之后的结果,则答案为:

x=1log2n[nand2x0](1)popcount(mx)i=02x1(1)popcount(i)f(mx+i)=x=1log2n[nand2x0](1)popcount(mx)i=02x1j=0k1aj(mx+i)j(1)popcount(i)=j=0k1ajt=0j(jt)x=1log2n[nand2x0](1)popcount(mx)mxjti=02x1(1)popcount(i)it\begin{aligned} &\sum_{x=1}^{\log_2 n}[n \operatorname{and} 2^x \neq 0](-1)^{\mathrm{popcount}(m_x)}\sum_{i=0}^{2^{x}-1}(-1)^{\mathrm{popcount}(i)}f(m_x+i)\\ =&\sum_{x=1}^{\log_2 n}[n \operatorname{and} 2^x \neq 0](-1)^{\mathrm{popcount}(m_x)}\sum_{i=0}^{2^{x}-1}\sum_{j=0}^{k-1} a_j(m_x+i)^j(-1)^{\mathrm{popcount}(i)}\\ =&\sum_{j=0}^{k-1} a_j\sum_{t=0}^{j}\dbinom{j}{t}\sum_{x=1}^{\log_2 n}[n \operatorname{and} 2^x \neq 0](-1)^{\mathrm{popcount}(m_x)}m_x^{j-t}\sum_{i=0}^{2^{x}-1}(-1)^{\mathrm{popcount}(i)}i^{t} \end{aligned}

g(x,t)=i=02x1(1)popcount(i)itg(x,t)=\sum\limits_{i=0}^{2^{x}-1}(-1)^{\mathrm{popcount}(i)}i^{t},类似上面的拆位我们把第 xx 位拆出来:

g(x,t)=g(x1,t)+i=2x12x1(1)popcount(i)it=g(x1,t)i=02x11(1)popcount(i)j=0t(tj)2x(tj)ij=g(x1,t)j=0t(tj)2x(tj)g(x1,j)\begin{aligned} g(x,t)&=g(x-1,t)+\sum\limits_{i=2^{x-1}}^{2^{x}-1}(-1)^{\mathrm{popcount}(i)}i^{t}\\ &=g(x-1,t)-\sum\limits_{i=0}^{2^{x-1}-1}(-1)^{\mathrm{popcount}(i)}\sum_{j=0}^{t}\dbinom tj2^{x(t-j)}i^j\\ &=g(x-1,t)-\sum_{j=0}^{t}\dbinom tj2^{x(t-j)}g(x-1,j) \end{aligned}

此时我们已经可以 O(k2logn)O(k^2 \log n) 递推求解,但这还不够。一个简单但不易观察到的性质是 x>tx>tg(x,t)=0g(x,t)=0,可以归纳法证明。此时 gg 的递推变为了 O(k3)O(k^3),原式的求和中 xx 也只用枚举到 tt

j=0k1ajt=0j(jt)x=1t[nand2x0](1)popcount(mx)mxjtg(x,t)\sum_{j=0}^{k-1} a_j\sum_{t=0}^{j}\dbinom{j}{t}\sum_{x=1}^{t}[n \operatorname{and} 2^x \neq 0](-1)^{\mathrm{popcount}(m_x)}m_x^{j-t}g(x,t)

这样就 O(k3)O(k^3) 做完了。

P3447 [POI2006]KRY-Crystals

题意

给出序列 a1na_{1\sim n},求满足以下条件的序列 bb 的个数:

  • i\forall i0biai0 \leq b_i \leq a_i
  • b1b2bn=0b_1\oplus b_2\oplus \ldots\oplus b_n=0

n50n \leq 50ai<2321a_i<2^{32}-1,保证答案小于 2642^{64}

题解

如果前面 n1n-1 个数已经填好,那么第 nn 个数只有一种选择,但它的上限会限制合法性。如果 an=+a_n = +\infty,则方案数就是 i=1n1(ai+1)\prod_{i=1}^{n-1}(a_i+1)

这启示我们从高位到低位考虑,不妨设所有 aia_i 中最高的位为 wwaia_i 包含最高位的 ii 的集合为 SS。如果存在一个包含最高位的 aa,它的 bbww 这一位不顶上界(即取 00)的情况,如果其非空子集 TT 内的 bib_i 最高位填的是 00,也就是非最高位不受限,那么只需要从 TT 集合中任取一个放最后「补漏」,其它随便取即可,方案数就是:

TS,T[ST is even](2w)T1i∉T(aimod2w+1)\sum_{T\subseteq S, T \neq \varnothing}[|S|-|T| \text{ is even}](2^w)^{|T|-1}\prod_{i \not\in T}(a_i\bmod 2^w+1)

这个式子可以一遍 DP 简单地 O(n)O(n) 算出,不赘述。剩下的情况只有 SS 内所有 bb 最高位都填 11,判断合法性后就是将所有数都去掉最高位之后的子问题了。故我们做 O(logm)O(\log m) 次 DP 即可求出答案,时间复杂度 O(nlogm)O(n \log m)

P7408 [JOI 2021 Final] ダンジョン 3

题意

n+1n+1 个加油站,第 iii1i-1 个之间距离 aia_i 个单位长度,第 ii 个加油站加单位油量需要花费 bib_i

车只能向右走,走 11 单位长度要用 11 单位油量,用完不能走。加油不能超过油量上限。

mm 组询问,每次给出 l,r,xl,r,x 表示一辆车从 ll 走到 rr 并且油量上限为 xx 需要花费的最小代价。

1n,m,ai,bi2×1051 \leq n,m,a_i,b_i \leq 2\times 10^51x1091 \leq x \leq 10^9

题解

令油量上限为 uu,有一个贪心:找到当前位置后第一个价格比它小的位置 xx,加油至能走到 xx 为止;若到 xx 的距离 u\ge u,则加满 uu 然后往后走一步。

考虑如何维护这个贪心:固定右端点,从右往左扫描左端点,维护价格递减的单调栈(为方便表述,令栈中元素是位置),栈顶即要找的位置。令当前位置为 iiii 加入单调栈后,策略的变化是用 bib_i 替换从 ii 到栈顶的前 uu 个单位的油,不足则全部替换。原因是,我找到原单调栈中与 ii 距离 u\ge u 的第一个位置,到达此位置时我一定没油,后面策略就不变了。

但询问的 uu 不等,就要讨论单调栈每一段的贡献。具体而言,假设我此时弹出 xx,弹出后的栈顶为 yy

  • uxiu\leq x-i:无贡献。
  • xi<ux-i<u:将 min(u+i,y)x\min(u+i,y)-x 单位油的价格由 bxb_x 替换为 bib_i,贡献 (bibx)(min(u+i,y)x)(b_i-b_x)(\min(u+i,y)-x)

容易发现这是个关于 uu 的分段一次函数,线段树可以维护,这样就解决 Subtask 3 了。

对于区间 [l,r][l,r] 的询问,我们找出 [ru,r][r-u,r] 中最小价格的位置 kk,则 kk 处的决策一定是加满油到走到 rr 为止,这段路与「从 kk 走到最后」的决策完全一致,所以 ans(l,r)=ans(l,+)ans(k,+)+bk(rk)\operatorname{ans}(l,r)=\operatorname{ans}(l,+\infty)-\operatorname{ans}(k,+\infty)+b_k(r-k)

只需要将右端点固定为最右边就可以算出 ans(i,+)\operatorname{ans}(i,+\infty),时间复杂度 O(nlogn)O(n \log n)