D1. Xor-Subsequence (easy version)
D1. Xor-Subsequence (easy version)
It is the easy version of the problem. The only difference is that in this version .
You are given an array of integers . Bryap wants to find the longest beautiful subsequence in the array.
An array , where , is a subsequence of length of the array .
Subsequence of length is called beautiful, if the following condition holds:
- For any () holds: .
Here denotes the bitwise XOR of and . For example, and .
Bryap is a simple person so he only wants to know the length of the longest such subsequence. Help Bryap and find the answer to his question.
Input
The first line contains a single integer () — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer () — the length of the array.
The second line of each test case contains integers () — the elements of the array.
It is guaranteed that the sum of over all test cases does not exceed .
Output
For each test case print a single integer — the length of the longest beautiful subsequence.
Example
input
3
2
1 2
5
5 2 4 3 1
10
3 8 8 2 9 1 6 2 8 3
output
2
3
6
Note
In the first test case, we can pick the whole array as a beautiful subsequence because .
In the second test case, we can pick elements with indexes , and (in -indexation). For this elements holds: and .
解题思路
如果我们选择了一个合法的序列,,那么必然有 。
定义状态 表示选择 作为最后一项的所有序列中长度的最大值,根据序列前一个元素是哪个进行状态划分,有状态转移方程
很明显如果直接暴力枚举 那么时间复杂度是 的。观察式子 ,此时已经有 了,意味着 要变小或 变大。注意到 最大只有 ,在二进制下只有最低 位是有效的,即 只对 的最低 位有影响,同理 只对 的最低 位有影响。考虑 和 除了最低 位之外的位,即 和 ,如果 ,那么无论 和 的值是多少,必然有 ,所以 的下界就是 ,也就是把 的最低 位都置 ,这样 和 在除了最低 位之外的位都一样。为此 的枚举范围应该是 ,区间大小最大只有 。
AC 代码如下,时间复杂度为 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
int a[N];
int f[N];
void solve() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", a + i);
}
int ret = 0;
for (int i = 0; i < n; i++) {
f[i] = 1;
for (int j = i >> 8 << 8; j < i; j++) {
if ((a[j] ^ i) < (a[i] ^ j)) f[i] = max(f[i], f[j] + 1);
}
ret = max(ret, f[i]);
}
printf("%d\n", ret);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
参考资料
Codeforces Round #815 (Div. 2) 讲解:https://www.bilibili.com/video/BV1mG4y1a7QS/
Codeforces Round #815 (Div. 2) Editorial:https://codeforces.com/blog/entry/106136
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17865151.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效