0x00 前置芝士

数位dp考试里出现的小神题??

显然考场会选择打表找规律。

数位dp + 矩阵快速幂


0x01 题目描述

给定正整数 \(n\),现有如下方程 \(x \bigoplus 3x = 2x\),其中 \(\bigoplus\) 表示按位异或。

任务如下:

  1. 求出小于等于 \(n\) 的正整数中,有多少个数是该方程的解
  2. 求出小于等于 \(2^n\) 的正整数中,有多少个数是该方程的解,答案对 \(10^9 + 7\) 取模

0x02 分析

第一问

试证明满足 \(x \bigoplus 2 \times x = 3 \times x\) 的 \(x\),二进制拆分数列里没有相邻的 \(1\)。

条件可化为 \(x \bigoplus 2 \times x = x + 2 \times x\)。

若有相邻的 \(1\),二倍后即错位相加,定会产生多余进位,得不到右边的答案,故矛盾。故原命题成立。

例:

0 0 1 1
0 1 1 0

推论: 设 \(f(a, b)(b \in \{0, 1\})\) 表示第 \(a - 1\) 一位为 \(b\) 的数中共有多少个满足条件的数。

则 \(f(a, 0) = f(a - 1, 1) + f(a - 2, 0)\),\(f(a, 1) = f(a - 1, 0)\)。证明显然。

第二问

试证明小于 \(2 ^ n\) 的满足 \(x \bigoplus 2 \times x = 3 \times x\) 的 \(x\) 的个数为斐波那契数列第 \(n\) 项。

记 \(g(a) = f(a, 0) + f(a, 1)\)。利用第一问结论推论,推导如下。

\(g(a) = f(a, 0) + f(a, 1)\)

\(g(a) = f(a - 1, 1) + f(a - 1, 0) + f(a - 1, 0)\)

\(g(a) = g(a - 1) + f(a - 2, 1) + f(a - 2, 0)\)

\(g(a) = g(a - 1) + g(a - 2)\)


0x04 具体实现

#include <cstdio>
#include <cstring>
using namespace std; typedef long long LL;
const int MAXL = 105;
const int MAXN = 4;
const int mod = 1e9 + 7;
int flag[MAXL], a[MAXL];
LL dp[MAXL][MAXL][2][2]; struct Matrix {
int n, m;
LL mp[MAXN][MAXN];
Matrix() { memset(mp, 0, sizeof mp); }
Matrix operator * (const Matrix &x) const {
Matrix ans;
ans.n = n;
ans.m = x.m;
for (int i = 1; i <= ans.n; i++)
for (int j = 1; j <= ans.m; j++)
for (int k = 1; k <= m; k++)
ans.mp[i][j] = (ans.mp[i][j] + (mp[i][k] * x.mp[k][j]) % mod) % mod;
return ans;
}
}; Matrix Quick_pow(Matrix a, LL x) {
Matrix ans;
ans.n = 2;
ans.m = 2;
ans.mp[2][2] = 1;
ans.mp[1][1] = 1;
ans.mp[1][2] = 0;
ans.mp[2][1] = 0;
while (x) {
if (x & 1)
ans = ans * a;
a = a * a;
x >>= 1;
}
return ans;
} LL dfs(int p, int last, bool k, bool limit, bool t) {
if(p <= 0)
return !t && k;
if(!limit && dp[p][last][t][k] != -1)
return dp[p][last][t][k];
int up = limit ? flag[p] : 1;
LL ans = 0;
for(int i = 0; i <= up; i++)
ans = (ans + dfs(p - 1, i, t || last == -1 || (k && i == 1 && last == 0)
|| (k && i == 0 && last == 0) || (k && i == 0 && last == 1), limit && (i == up), (t && !i)));
if(!limit)
dp[p][last][t][k] = ans;
return ans;
} LL Query(LL x) {
int len = 0;
while(x) {
flag[++len] = (x & 1);
x >>= 1;
}
return dfs(len, -1, true, true, true);
} int main() {
memset(dp, -1, sizeof dp);
int T;
scanf ("%d", &T);
while(T--) {
LL n;
scanf ("%lld", &n);
printf("%lld\n", Query(n));
Matrix A, cur, ans;
A.n = 2, A.m = 2;
A.mp[1][1] = 0;
A.mp[1][2] = 1;
A.mp[2][1] = 1;
A.mp[2][2] = 1;
ans = Quick_pow(A, n);
cur.n = 1, cur.m = 2;
cur.mp[1][1] = 1;
cur.mp[1][2] = 1;
ans = cur * ans;
printf("%lld\n", ans.mp[1][2] % mod);
}
return 0;
}

Solution -「校内题」Xorequ的更多相关文章

  1. Solution -「校内题」矩阵求和

    Description 共 \(T\) 组数据.对于每组数据,给定 \(a, b, n\),求 \(\sum_{i = 1}^{n} \sum_{j = 1}^{n} \gcd(a^i - b^i, ...

  2. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  3. Solution -「ARC 101D」「AT4353」Robots and Exits

    \(\mathcal{Description}\)   Link.   有 \(n\) 个小球,坐标为 \(x_{1..n}\):还有 \(m\) 个洞,坐标为 \(y_{1..m}\),保证上述坐标 ...

  4. Solution -「国家集训队」「洛谷 P2619」Tree I

    \(\mathcal{Description}\)   Link.   给一个 \(n\) 个点 \(m\) 条边的带权无向图,边有权值和黑白颜色,求恰选出 \(K\) 条白边构成的最小生成树.    ...

  5. Solution -「ARC 104C」Fair Elevator

    \(\mathcal{Description}\)   Link.   数轴从 \(1\sim 2n\) 的整点上有 \(n\) 个闭区间.你只知道每个区间的部分信息(可能不知道左或右端点,或者都不知 ...

  6. Solution -「基环树」做题记录

    写的大多只是思路,比较简单的细节和证明过程就不放了,有需者自取. 基环树简介 简单说一说基环树吧.由名字扩展可得这是一类以环为基础的树(当然显然它不是树. 通常的表现形式是一棵树再加一条非树边,把图画 ...

  7. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  8. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  9. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

随机推荐

  1. Python技法:实现简单的递归下降Parser

    1. 算术运算表达式求值 在上一篇博文<Python技法:用re模块实现简易tokenizer>中,我们介绍了用正则表达式来匹配对应的模式,以实现简单的分词器.然而,正则表达式不是万能的, ...

  2. 基于mybatis的java代码生成存储过程

    问题: 项目中目前使用mybatis操作数据库,使用插件(mybatis-generator)自动生成代码,对于增改查,使用存储过程实现了一版本,方便使用. insert代码生成器用法: insert ...

  3. 推荐 | Linux 思维导图整理(建议收藏)

    一个执着于技术的公众号 作者:小柑 来源:https://www.jianshu.com/p/59f759207862 今天整理了一下收集的 Linux 思维导图.上传的均为高清原图,双击即可查看,也 ...

  4. java高级用法之:JNA中的Structure

    目录 简介 native中的struct Structure 特殊类型的Structure 结构体数组作为参数 结构体数组作为返回值 结构体中的结构体 结构体中的数组 结构体中的可变字段 结构体中的只 ...

  5. Spring 源码(10)Spring Bean 的创建过程(1)

    Spring Bean的创建刚开始进行了一些准备工作,比如转换服务的初始化,占位符解析器的初始化,BeanDefinition元数据的冻结等操作,都是为了在创建Bean的过程中保证Bean的正确的创建 ...

  6. Vue的Vuex的使用

    一.Vuex是什么? 1:Vuex是一个专为vue.js应用程序开发的状态管理模式,核心就是一个store仓库,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 ...

  7. Arthas常用功能及一次线上问题排查

    一.Arthas简介 Arthas是Alibaba开源的Java诊断工具,功能很强大,它是通过Agent方式来连接运行的Java进程.主要通过交互式来完成功能. https://arthas.aliy ...

  8. nginx反向代理获取用户真实ip

    nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...

  9. 印尼医疗龙头企业Halodoc的数据平台转型之Lakehouse架构

    1. 摘要 在 Halodoc,我们始终致力于为最终用户简化医疗保健服务,随着公司的发展,我们不断构建和提供新功能. 我们两年前建立的可能无法支持我们今天管理的数据量,以解决我们决定改进数据平台架构的 ...

  10. 浅析 2D 组态与 2.5D 组态的区别 | 空调装配生产线与化工安全流程

    前言 为了更有效辨别 2D 与 2.5D 之间的区别,图扑软件选用 2D 空调装配生产线与 2.5D 化工厂安全流程作比较.通过自主研发的 HT 产品,采用 B/S 架构快速搭建零代码拖拽式 Web ...