首页 > 其他分享 >D2. Xor-Subsequence (hard version)

D2. Xor-Subsequence (hard version)

时间:2023-11-29 17:45:21浏览次数:53  
标签:Xor 高位 int hard tr ret Subsequence test oplus

D2. Xor-Subsequence (hard version)

It is the hard version of the problem. The only difference is that in this version $a_i \le 10^9$.

You are given an array of $n$ integers $a_0, a_1, a_2, \ldots a_{n - 1}$. Bryap wants to find the longest beautiful subsequence in the array.

An array $b = [b_0, b_1, \ldots, b_{m-1}]$, where $0 \le b_0 < b_1 < \ldots < b_{m - 1} < n$, is a subsequence of length $m$ of the array $a$.

Subsequence $b = [b_0, b_1, \ldots, b_{m-1}]$ of length $m$ is called beautiful, if the following condition holds:

  • For any $p$ ($0 \le p < m - 1$) holds: $a_{b_p} \oplus b_{p+1} < a_{b_{p+1}} \oplus b_p$.

Here $a \oplus b$ denotes the bitwise XOR of $a$ and $b$. For example, $2 \oplus 4 = 6$ and $3 \oplus 1=2$.

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 $t$ ($1 \leq t \leq 10^5$)  — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($2 \leq n \leq 3 \cdot 10^5$) — the length of the array.

The second line of each test case contains $n$ integers $a_0,a_1,...,a_{n-1}$ ($0 \leq a_i \leq 200$) — the elements of the array.

It is guaranteed that the sum of $n$ over all test cases does not exceed $3 \cdot 10^5$.

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 $1 \oplus 1 < 2 \oplus 0$.

In the second test case, we can pick elements with indexes $1$, $2$ and $4$ (in $0$-indexation). For this elements holds: $2 \oplus 2 < 4 \oplus 1$ and $4 \oplus 4 < 1 \oplus 2$.

 

解题思路

  dp 的分析与 D1. Xor-Subsequence (easy version) 一样。观察式子 $a_j \oplus i < a_i \oplus j$,意味着 $a_j \oplus i$ 和 $a_i \oplus j$ 的二进制的前 $k-1$ 个高位相同,第 $k$ 个高位不同,且 $a_j \oplus i$ 的第 $k$ 个高位是 $0$,$a_i \oplus j$ 的第 $k$ 个高位是 $1$。只考虑前 $k-1$ 个高位,由于都相同因此有 $a_j \oplus i = a_i \oplus j$,从而有 $a_i \oplus i = a_j \oplus j$。为此可以考虑在枚举完 $a_i$ 后,把 $a_i \oplus i$ 插到 Trie 中。

  为此就很容易想到对于 $a_i$,枚举 $k$ 表示前 $k-1$ 个高位相同而第 $k$ 个高位不同,那么满足条件的 $a_j$ 和 $j$ 对应到 Trie 中就是从根节点开始走 $k-1$ 步,与 $a_i \oplus i$ 路径相同的 $a_j \oplus j$。第 $k$ 步取决于 $a_i \oplus i$ 的第 $k$ 个高位,如果 $a_i \oplus i$ 的第 $k$ 个高位是 $0$ 则走 $1$ 的分支,否则走 $0$ 的分支。

  为什么是这样子呢?列表格分类讨论就好了,讨论 $a_i, i, a_j, j$ 的第 $k$ 个高位的值(要满足 $a_j$ 与 $i$ 相同,$a_i$ 与 $j$ 相同),比较 $a_i \oplus i$ 与 $a_j \oplus j$。

$a_j$ $i$ $a_i$ $j$ $a_i \oplus i$ $a_j \oplus j$
$0$ $0$ $0$ $1$ $0$ $1$
$0$ $0$ $1$ $0$ $1$ $0$
$1$ $1$ $0$ $1$ $1$ $0$
$1$ $1$ $1$ $0$ $0$ $1$

  可以发现如果第 $k$ 个高位不同,那么对于第 $k$ 个高位必然有 $a_i \oplus i \ne a_j \oplus j$,所以应该走相反的分支。

  另外 $a_i$ 与 $j$ 的第 $k$ 个高位还要不同,因此可以维护一个 $g(u,0/1)$,表示考虑所有的 $a_j, \, j \in [0,i-1]$ 中,关于 $a_j \oplus j$ 从根节点走 $k$ 步到节点 $u$,且 $j$ 的第 $k$ 个高位是 $0/1$ 的所有 $f(j)$ 的最大值。

  剩余的细节请见代码。

  AC 代码如下,时间复杂度为 $O(n \log{A})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 3e5 + 10, M = N * 30;

int a[N];
int f[N];
int tr[M][2], g[M][2], idx;

void add(int x, int y) {
    int t = x ^ y, p = 0;
    for (int i = 29; i >= 0; i--) {
        int u = t >> i & 1;
        if (!tr[p][u]) tr[p][u] = ++idx;
        p = tr[p][u];
        g[p][y >> i & 1] = max(g[p][y >> i & 1], f[y]);
    }
}

int query(int x, int y) {
    int t = x ^ y, p = 0, ret = 1;
    for (int i = 29; i >= 0; i--) {
        int u = t >> i & 1;
        if (tr[p][!u]) ret = max(ret, g[tr[p][!u]][~x >> i & 1] + 1);
        p = tr[p][u];
        if (!p) break;
    }
    return ret;
}

void solve() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
    }
    idx = 0;
    for (int i = 0; i < n * 30; i++) {
        tr[i][0] = tr[i][1] = g[i][0] = g[i][1] = 0;
    }
    int ret = 0;
    for (int i = 0; i < n; i++) {
        f[i] = query(a[i], i);
        add(a[i], i);
        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

  Codeforces Round #815 (Div. 2) D1 D2(字典树 + dp):https://zhuanlan.zhihu.com/p/555425330

标签:Xor,高位,int,hard,tr,ret,Subsequence,test,oplus
From: https://www.cnblogs.com/onlyblues/p/17865441.html

相关文章

  • ShardingSphere学习笔记
    MySQL7的root密码校验方式:mysql_native_passwordMySQL8的root密码校验方式:caching_sha2_password将mysql8的root密码校验方式改为7的:ALTERUSER'root'@'%'IDENTIFIEDWITHmysql_native_passwordBY'123456'; 进入docker容器:防止中文显示乱码:dockerexec-itxxx-na......
  • sharding分表应用笔记(四)——踩坑记录
    sharding分表应用笔记(四)——踩坑记录(更新中)目录sharding分表应用笔记(四)——踩坑记录(更新中)1sql语句使用时不带分表关键字段2在事务中触发数据源路由1sql语句使用时不带分表关键字段如果不带分表关键字段,会默认进行全节点域遍历。如果没有预先创建所有的表节点,会报错提示找不......
  • 简单的文件加密程序(md5xor异或winlinux)
    简介小程序是基于md5+password+xor的组合方式来加密文件。程序支持跨平台(Windows/Linux)。使用方法: 源文件清单:main.c  md5.c  md5.h  setup.sh 完整代码(main.c):#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#i......
  • 【刷题笔记】115. Distinct Subsequences
    题目Giventwostrings s and t,return thenumberofdistinctsubsequencesof s whichequals t.Astring's subsequence isanewstringformedfromtheoriginalstringbydeletingsome(canbenone)ofthecharacterswithoutdisturbingtheremainingch......
  • Mybatis-Plus集成Sharding-JDBC与Flyway实现多租户分库分表
    背景公司产品部收到了一些重要客户的需求,他们希望能够依赖独立的数据库存储来支持他们的业务数据。与此同时,仍有许多中小客户,可以继续使用公共库以满足其需求。技术实现方面,此前持久层框架使用的Mybatis-plus,部分业务场景使用到了Sharding-JDBC用于分表,另外,我们的数据库版本控制工......
  • Mybatis-Plus集成Sharding-JDBC与Flyway实现多租户分库分表
    背景公司产品部收到了一些重要客户的需求,他们希望能够依赖独立的数据库存储来支持他们的业务数据。与此同时,仍有许多中小客户,可以继续使用公共库以满足其需求。技术实现方面,此前持久层框架使用的Mybatis-plus,部分业务场景使用到了Sharding-JDBC用于分表,另外,我们的数据库版本控制......
  • sharding分表应用笔记(三)——多数据源路由
    sharding分表应用笔记(三)——多数据源路由目录sharding分表应用笔记(三)——多数据源路由1背景2配置2.1命名空间配置2.2spring-jdbc路由配置3指定路由3.1自定义注解3.2功能实现3.3用例1背景应用背景:物理数据源只有一个;对于部分数据量大的表实行按月分表处理,其他的表仍然......
  • T399750 Cell kingdom(Hard) 题解
    LinkT399750Cellkingdom(Hard)Qustion第一天产生\(1\)个细胞,之后的每一天,一个细胞都会分裂成\(8\)个和自己一样的细胞,每个细胞在第三天都会自爆并且带走当天产生的\(6\)个细胞,求第\(x\)天有多少细胞Solution我们设\(F[i]\)表示第\(i\)天产生的新细胞个数那么可......
  • [USACO22OPEN] Up Down Subsequence P
    [USACO22OPEN]UpDownSubsequenceP注意到这个问题是不弱于直接求LIS的,因此考虑dp。设\(f_i\)表示以\(i\)结尾的最长这个什么串的长度,显然没办法直接转移,那么暴力的想法就是多设一维,这样自然就寄了。我们考虑到这样一件事情:如果我们假装对于所有的\(j\),\(j<f_i\)时......
  • 非常经典的一道SQL报错注入题目[极客大挑战 2019]HardSQL 1(两种解法!)
    题目环境:<br/>没错,又是我,这群该死的黑客竟然如此厉害,所以我回去爆肝SQL注入,这次,再也没有人能拿到我的flag了做了好多这个作者出的题了,看来又要上强度了判断注入类型username:adminpassword:1这里把参数password作为注入点<br/>1'<br/>单引号的字符型注入万能密码注......