我们可以知道异或可以看成不进位的加法,那么我们就可以得到 \(a + b = a\) ^ \(b + ((a \& b) << 1)\),不难发现 \(\frac{v - u}{2}\) 就是 \(a \& b\) 也就是 \(a, b\) 中同时为 \(1\) 的位置,那么只需要满足 \(\frac{v - u}{2} \& u = 0\) 且 \((i - j) \% 2 = 0\)我们就能合理分配 \(a, b\) 的 \(0 / 1\) 使得 \(u, v\) 能够被表示出来。于是我开始从 \(u, v\) 的判定条件入手,枚举 \(u\) 然后可以从最高位往下做一个 \(dp\) 这样就可以做到 \(O(n \log n)\) 但想了很久都没办法继续优化下去了。

当我们陷入死胡同的时候,不妨走出来换一个方向再继续。因为 \(a + b = v \le n\) 因此我们可以直接考虑枚举这样的 \((a, b)\) 来判定哪些 \((u, v)\) 是合法的,于是我们有了这样一个想法,我们能否将问题转化成统计一些合法的 \((a, b)\) 以知道 \((u, v)\) 的数量呢?实际上我们可以考虑一对合法的 \((u, v)\) 可以被那些 \((a, b)\) 表示出来,我们单独考虑 \(u\) 的二进制位,如果这个位置上是 \(1\) 那么就表示 \(a, b\) 在这一位上有一个是 \(1\) 另一个是 \(0\),如果是 \(u\) 在这一位上是 \(0\) 就表示 \((a, b)\) 在这一位上要么都是 \(1\) 要么都是 \(0\),可以发现因为 \(a + b = v\) 是确定的,因此都是 \(1\) 和都是 \(0\) 的位置是确定的,那么同一对 \((u, v)\) 能被不同的 \((a, b)\) 表示出来当且仅当 \((a, b)\) 在某一位上一个是 \(1\) 一个是 \(0\),因此我们在统计这样 \((a, b)\) 时可以钦定 \(a\) 的每一位都不大于 \(b\),这样就能不重不漏地统计完所有答案了。

于是原问题被我们转化为,统计二元组 \((a, b)\) 的数量满足 \(0 \le a \le b \le n, a + b \le n\) 且在二进制位下 \(a\) 的每一位都不大于 \(b\)。于是我们可以考虑令 \(dp_i\) 表示 \(a + b \le i\) 的合法二元组数量,因为要满足二进制位下 \(a\) 的每一位不大于 \(b\),因此我们在考虑往 \(a, b\) 末尾同时加入一个数时只可能是 \((0, 0) / (0, 1) / (1, 1)\),对应着转移就是 \(dp_i = dp_{\lfloor \frac{i}{2} \rfloor} + dp_{\lfloor \frac{i - 1}{2} \rfloor} + dp_{\lfloor \frac{i - 2}{2} \rfloor}\)。可以用记忆化搜索实现这个过程,可以发现每次往下递归时要求的 \(dp\) 值实际上只有两个,如果 \(i = 2k + 1\) 且 \(k\) 为奇数时我们恰好发现下面需要求的 \(dp\) 值又只有一边,如果 \(k\) 为偶数可以发现最多经过 \(\log n\) 次就会变成 \(k\) 为奇数的情况,而每次除了 \(\frac{k}{2}\) 的部分最多往下多算两次,而最开始 \(i = 2k\) 时与这里类似,因此我们有效的合法状态大约是 \(O(3 \log n)\) 的,实际上效率非常高,有效状态在 \(O(2 \log n) \sim O(3 \log n)\) 之间。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Mod 1000000007
#define rep(i, l, r) for(int i = l; i <= r; ++i)
int n, cnt;
unordered_map <int, int> dp;
int read(){
char c; int x = 0, f = 1;
c = getchar();
while(c > '9' || c < '0'){ if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int Inc(int a, int b){
return (a += b) >= Mod ? a - Mod : a;
}
int dfs(int n){
if(dp[n]) return dp[n];
return dp[n] = Inc(Inc(dfs(n / 2), dfs((n - 1) / 2)), dfs((n - 2) / 2));
}
signed main(){
n = read(), dp[0] = 1, dp[1] = 2;
printf("%lld\n", dfs(n));
return 0;
}

可以发现因为是递推式,其实我们可以打表看出规律,但这个递推式有点刁钻,也可能是我太弱了吧。以后这种二进制下满足某种条件的数的个数递推式可以考虑在 \(\lfloor \frac{i}{2} \rfloor\) 附近的值考虑。

AT2272 [ARC066B] Xor Sum的更多相关文章

  1. AT2272 [ARC066B] Xor Sum 题解

    题目连接:传送门 分析 这道题只看题目中给的样例是找不出规律的 所以我们可以打一下表 1, 2, 4, 5, 8, 10, 13, 14, 18 如果你还是没有看出什么规律的话,我们可以从OEIS上搜 ...

  2. HDU 4825 Xor Sum(经典01字典树+贪心)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  3. 字典树-百度之星-Xor Sum

    Xor Sum Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包括了N个正整数,随后 Prometheu ...

  4. HDU 4825 Xor Sum 字典树+位运算

    点击打开链接 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) ...

  5. 2014百度之星第三题Xor Sum(字典树+异或运算)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  6. Xor Sum 01字典树 hdu4825

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total S ...

  7. hdu 4825 Xor Sum (01 Trie)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 题面: Xor Sum Time Limit: 2000/1000 MS (Java/Others) ...

  8. HDU--4825 Xor Sum (字典树)

    题目链接:HDU--4825 Xor Sum mmp sb字典树因为数组开的不够大一直wa 不是报的 re!!! 找了一下午bug 草 把每个数转化成二进制存字典树里面 然后尽量取与x这个位置上不相同 ...

  9. hdu 4825 Xor Sum trie树

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Proble ...

随机推荐

  1. rsync 守护进程及实时同步

    目录 rsync 守护进程及实时同步 rsync简介 rsync特性 rsync应用场景 cp命令 scp命令 rsync的传输方式 rsync的传输模式 rsync实际使用 rsync命令 案例 r ...

  2. Towards Evaluating the Robustness of Neural Networks

    目录 概 主要内容 基本的概念 目标函数 如何选择c 如何应对Box约束 attack attack attack Nicholas Carlini, David Wagner, Towards Ev ...

  3. HDFS源码解析:教你用HDFS客户端写数据

    摘要:终于开始了这个很感兴趣但是一直觉得困难重重的源码解析工作,也算是一个好的开端. 本文分享自华为云社区<hdfs源码解析之客户端写数据>,作者: dayu_dls. 在我们客户端写数据 ...

  4. CS5211替代LT7211 DP转LVDS芯片方案 替代龙迅LT7211方案

    LT7211是一种用于虚拟现实/显示应用的高性能C/DP1.2至LVDS芯片方案.LT7211支持DP1.2输入,LT7211可以配置为1.2.4车道,还支持车道交换功能.自适应均衡使其适用于长电缆应 ...

  5. python_接口自动化测试_处理参数替换

    在进行自动化测试时,通常会存在A接口用例的返回值是B接口用例的入参这样的情况 可进行如下方式处理: step1.处理A用例时,在响应结果中提取出该数据的值,并赋给一变量,比如 exeId = res. ...

  6. 使用用支付宝时,返回的数据中subject为中文时验签失败

    解决方法为: 来自为知笔记(Wiz)

  7. spring security 关于 http.sessionManagement().maximumSessions(1);的探究

    1.前言 spring security 支持对session的管理 , http.sessionManagement().maximumSessions(1);的意思的开启session管理,ses ...

  8. 35个JAVA性能优化总结

    原文链接:http://mp.weixin.qq.com/s/J614jGM_oMrzdeS_ivmhvA   代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对 ...

  9. Go语言系列之函数

    函数是组织好的.可重复使用的.用于执行指定任务的代码块.本文介绍了Go语言中函数的相关内容. 函数 Go语言中支持函数.匿名函数和闭包,并且函数在Go语言中属于"一等公民". 函数 ...

  10. Echart可视化学习(八)

    文档的源代码地址,需要的下载就可以了(访问密码:7567) https://url56.ctfile.com/f/34653256-527823386-04154f 正文: 新增需求 点击 2020年 ...