数位动态规划中的区间异或
题解
问题为求$\sum_{i=L}^R f(i \oplus x)^2$
先将区间分成两个前缀的差,现在只需要考虑$[0,R] \oplus x$
从高到低枚举最高位$w$
设$x’$表示$x$去掉第$w$位的值
设$x^w$表示只保留$x$的$[0,w-1]$位的值
如果$R<2^w$,递归到更小的$w$进行处理
如过$R\geq 2^w$,那么可以考虑$[0,R]=[0,2^w-1]+[2^w,R]$
$[0,2^w-1]\oplus x$
$=[0,2^w-1] \oplus x^w\oplus(x\oplus x^w)$
$=[0,2^w-1]\oplus(x\oplus x^w)$
$=[(x\oplus x^w),(x\oplus x^w)+2^w-1]$
(这是因为异或的逆元即为自己本身,$a\oplus x=b$等价于$b\oplus x=a$,所以$[0,2^w-1]$中的数在异或后两两互换,所以$[0,2^w-1]\oplus x^w =[0,2^w-1]$)
$[2^w,R]\oplus x = [0,R-2^w]\oplus (x\oplus 2^w)$(此处显然有$R-2^w<2^w$),最高位变小,这部分递归到更小的$w$用相同的方法处理即可
这样就能把$[0,R]\oplus x$分成$O(logn)$个连续的区间,问题转化为求$\sum_{i=0}^R f(i)^2$
!注意!:对于异或问题,存在单调性的问题,利用数位动态规划的思想根据最高位取值为$0/1$将集合划分为两部分进行分治是很常用的做法。
代码
|
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment