[题解] 序列(sequence)
题目大意#
给定一个长度为 的非负整数序列 ,和一个正整数 。序列 满足 。定义一个长度为 的非负整数序列 是合法的,当且仅当其满足如下三个条件:
(1), ;
(2),这里的 表示二进制按位与;
(3),这里的 表示二进制按位或。
请你求出,有多少个满足条件的序列 。由于答案可能很大,你只需要输出其在模 意义下的结果。
数据范围:。
时间限制:2000ms
空间限制:1024MB
解题思路#
首先要有判断从哪个角度入手问题比较可做的能力,可以发现如果想要从 数组入手不太容易,于是考虑从对应的角度去考虑。
boshi:一一对应。
把 记作 , 记作 ,不难发现一组合法的 即对应一个满足条件的 序列。而 和 相互独立,于是考虑分别计数。
又由于是位运算相关,故按位考虑,设 表示从高到低考虑到第 位, 间的数字还是相同的,然后按照下一位枚举断点转移即可。
#include <bits/stdc++.h>
using namespace std;
const int N(105), M(30), mod(1e9 + 7);
int n, m, a[N];
int f[M][N][N];
inline void read(int &x){
x = 0; int f = 1, c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)) x = x * 10 + c - 48, c = getchar();
x *= f;
}
inline void MOD(int &x){ x = x + ((x >> 31) & mod); }
inline void init(){ memset(f, -1, sizeof(f)); }
int dfs(int b, int l, int r, int op){
if(b == -1) return 1; if(l > r) return 1;
if(~f[b][l][r]) return f[b][l][r];
f[b][l][r] = 0;
int L = r; while(l <= L && ((a[L] >> b) & 1) == op) --L;
for(int i(L); i <= r; ++i)
MOD(f[b][l][r] += 1LL * dfs(b - 1, l, i, op) * dfs(b - 1, i + 1, r, op) % mod - mod);
return f[b][l][r];
}
int main(){
freopen("sequence.in", "r", stdin);
freopen("sequence.out", "w", stdout);
read(n), read(m);
for(int i(1); i <= n; ++i) read(a[i]);
int And, Or, ans;
init(), And = dfs(m - 1, 1, n, 1);
init(), Or = dfs(m - 1, 1, n, 0);
ans = 1LL * And * Or % mod;
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现