AT2272 [ARC066B] Xor Sum
我们可以知道异或可以看成不进位的加法,那么我们就可以得到 \(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的更多相关文章
- AT2272 [ARC066B] Xor Sum 题解
题目连接:传送门 分析 这道题只看题目中给的样例是找不出规律的 所以我们可以打一下表 1, 2, 4, 5, 8, 10, 13, 14, 18 如果你还是没有看出什么规律的话,我们可以从OEIS上搜 ...
- HDU 4825 Xor Sum(经典01字典树+贪心)
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Total ...
- 字典树-百度之星-Xor Sum
Xor Sum Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包括了N个正整数,随后 Prometheu ...
- HDU 4825 Xor Sum 字典树+位运算
点击打开链接 Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) ...
- 2014百度之星第三题Xor Sum(字典树+异或运算)
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Total ...
- Xor Sum 01字典树 hdu4825
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total S ...
- hdu 4825 Xor Sum (01 Trie)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 题面: Xor Sum Time Limit: 2000/1000 MS (Java/Others) ...
- HDU--4825 Xor Sum (字典树)
题目链接:HDU--4825 Xor Sum mmp sb字典树因为数组开的不够大一直wa 不是报的 re!!! 找了一下午bug 草 把每个数转化成二进制存字典树里面 然后尽量取与x这个位置上不相同 ...
- hdu 4825 Xor Sum trie树
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Proble ...
随机推荐
- [炼丹术]yolact训练模型学习总结
yolact训练模型学习总结 一.YOLACT介绍(You Only Look At CoefficienTs) 1.1 简要介绍 yolact是一种用于实时实例分割的简单.全卷积模型. (A sim ...
- [Error]ValueError: Object arrays cannot be loaded when allow_pickle=False
问题描述使用numpy的函数 numpy.load() 加载数据时报错: ValueError: Object arrays cannot be loaded when allow_pickle=Fa ...
- CS5216|DP1.2转HDMI1.4音视频转换芯片|CS5216参数
Capstone CS5216是一款用于DP1.2转HDMI1.4音视频转换芯片.CS5216是HDMI 电平移位器/中继器专为2型双模Display Port(DP++)电缆适配器应用而设计.它设计 ...
- 【算法】01-数据结构概述(注意区分jvm堆与堆/jvm栈与栈)
[算法]01-数据结构概述(注意区分jvm堆与堆/jvm栈与栈) 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有 ...
- 编写Java程序,实现对兵营类的封装,将兵营类中的所有属性设置为私有访问权限,方法设置为公有访问权限
返回本章节 返回作业目录 需求说明: 实现对兵营类的封装 将兵营类中的所有属性设置为私有访问权限. 将兵营类中所有属性的赋值方法设置为公有访问权限. 要求兵营名称的长度在4-8位之间. 要求兵营士兵的 ...
- CGO快速入门
1. 通过`improt "C"`语句开启CGO特性2. `/**/`中间是C代码,之后接 import "C" 如果存在空行 就会报错.could not d ...
- hisql 高级功能数据检测将错误数据拦截在系统外 一
hisql github源码下载 git clone https://github.com/tansar/HiSql.git 在设计第二范式数据库时经常会把可能重复的数据单独做一种表关联,但是在写入表 ...
- 带你认识FusionInsight Flink:既能批处理,又能流处理
摘要:本文主要介绍了FusionInsight Flink组件的基本原理.Flink任务提交的常见问题.以及最佳实践FAQ. 本文分享自华为云社区<FusionInsight HD Flink组 ...
- python 面向对象:类方法&静态方法
一.类方法 1.1 概念和语法说明 类方法就是针对类对象定义的方法.在类方法内部可以直接访问类属性或者调用其他的类方法 语法如下: @classmethod def 类方法名(cls): pass 说 ...
- js获取设备内网ip
可以直接使用,不需要导入其他配置 看代码 1 <script> 2 //获取内网ip 3 var RTCPeerConnection = window.RTCPeerConnection ...