[DP记录]AT2272 [ARC066B] Xor Sum
command_block
2021-05-17 09:37:48
**题意** : 给出正整数 $n$。
求出满足下列条件的数对 $(u,v)$ 的数目 :
- $u,v\in[0,n]∩\rm Z$
- 存在 $a,b\in \rm N$ 满足 $a{\ \rm xor\ }b=u,\ a+b=v$。
答案对 $10^9+7$ 取模。
$n\leq 10^{18}$ ,时限$\texttt{2s}$。
------------
由于异或是不进位的加法,故 $a{\ \rm xor\ }b\leq a+b$。
所以所有合法数对必然有 $u\leq v$ ,只需进一步限制 $v\leq n$ 即可。
记 $f_i$ 为 $v=i$ 时符合题意的 $u$ 的个数。答案即为 $\sum_{i=1}^nf_i$。
考虑利用递推求解 $f_v$。
边界 : $f_0=1$。
- 若 $v$ 是奇数,则 $a,b$ 中必有且仅有一者为奇数。
去掉 $a,b$ 的最后一位,则相当于 $v\leftarrow (v-1)/2$。
此时 $f_v=f_{(v-1)/2}$。
- 若 $v$ 是正偶数,则 $a,b$ 或者全是偶数,或者全是奇数。
去掉 $a,b$ 的最后一位,则相当于 :
- (全偶) $v\leftarrow v/2$。
- (全奇) $v\leftarrow (v-2)/2$。
此时 $f_v=f_{v/2}+f_{(v-2)/2}$。
已经可以 $O(n)$ 求解各个 $f$。
记 $s_i=\sum_{j=1}^if_j$ ,目标是求出 $s_n$。
考虑 $s$ 的递推式 :
- $i$ 为偶数
$$
\begin{aligned}
s_i&=f_0+\sum\limits_{i=0}^{n/2-1}f_{2i+1}+\sum\limits_{i=1}^{n/2}f_{2i}\\
&=f_0+\sum\limits_{i=0}^{n/2-1}f_{i}+\sum\limits_{i=1}^{n/2}f_{i}+f_{i-1}\\
&=2s_{n/2-1}+s_{n/2}
\end{aligned}
$$
- $i$ 为奇数(且 $i>1$)
$$
\begin{aligned}
s_i&=f_0+\sum\limits_{i=0}^{(n-1)/2}f_{2i+1}+\sum\limits_{i=1}^{(n-1)/2}f_{2i}\\
&=f_0+\sum\limits_{i=0}^{(n-1)/2}f_{i}+\sum\limits_{i=1}^{(n-1)/2}f_{i}+f_{i-1}\\
&=2s_{(n-1)/2}+s_{(n-1)/2-1}
\end{aligned}
$$
记忆化搜索即可,可以证明复杂度为 $O\big({\rm poly}(\log n)\big)$。
```cpp
#include<algorithm>
#include<cstdio>
#include<map>
#define ll long long
using namespace std;
const int mod=1000000007;
map<ll,int> o;
int dfs(ll n)
{
if (o.find(n)!=o.end())return o[n];
if (n<=1)return n+1;
return o[n]=(n&1) ? (2ll*dfs(n/2)+dfs(n/2-1))%mod : (2ll*dfs(n/2-1)+dfs(n/2))%mod;
}
int main()
{
ll n;scanf("%lld",&n);
printf("%lld",dfs(n));
return 0;
}
```