本文将同步发布于:

题目

题目链接:gym102331B

题意概述

给你一个长度为 \(n\) 的序列 \(a_i\),求一个最长的子序列满足所有子序列中的元素两两满足 \(a_i\oplus a_j\geq x\),其中 \(\oplus\) 表示按位异或。

题解

发现性质

我们发现 \(p\oplus q\geq x\) 这个性质不是很好处理,决定通过研究异或的性质来解决问题。

我们考虑一个数 \(a\),若其满足 \(< x\),那么一定满足下面的情况:

  • 存在一个 \(i\) 满足 \(a\) 与 \(x\) 在 \([i+1,\infty)\) 位上相同,在第 \(i\) 位上有 \(a<x\)。

我们考虑 \(p\oplus q<x\),发现:

对于位置第一个不同的位置 \(i\),必然有 \(x_i=1,p_i=q_i\),而不是 \(p_i\neq q_i\)。

因此我们可以发现,对于三个数 \(a,b,c\),若其满足 \(a\leq b\leq c\),一定有 \(\min\{a\oplus b,b\oplus c\}\leq a\oplus c\)。

动态规划

得到了上面的性质,我们不难发现,如果我们将 \(a\) 从小到大排序,那么异或的最小值一定会出现在子序列的相邻两项之间。

换句话说,我们只需要保证子序列的所有相邻的项的异或 \(\geq x\),我们得到的就是一个合法的子序列。

设 \(f_i\) 表示以 \(i\) 结尾的最长的合法子序列,那么有转移方程:

\[f_i=\max_{a_i\oplus a_j\geq x}\{f_j\}+1
\]

时间复杂度为 \(\Theta(n^2)\)。

数据结构优化 dp

考虑到上面的转移与异或有关,我们不难想到可以利用 01-Trie 来优化转移过程。

具体地,我们在 Trie 上维护子树中 \(f_i\) 的最大值,每次转移时在 Trie 上根据与 \(x\) 的异或值选择左右儿子,如果另一棵子树内的所有值都满足 异或后 \(\geq x\),那么我们更新答案。

时间复杂度为 \(\Theta(n\log_2a)\)。

参考程序

#include<bits/stdc++.h>
using namespace std;
#define reg register
typedef long long ll;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
static char buf[100000],*p1=buf,*p2=buf;
inline int read(void){
reg char ch=getchar();
reg int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=10*res+(ch^'0'),ch=getchar();
return res;
} inline ll readll(void){
reg char ch=getchar();
reg ll res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=10*res+(ch^'0'),ch=getchar();
return res;
} const int MAXN=3e5+5;
const int MAXLOG2A=60;
const int mod=998244353; inline int add(reg int a,reg int b){
a+=b;
return a>=mod?a-mod:a;
} inline int sub(reg int a,reg int b){
a-=b;
return a<0?a+mod:a;
} inline int fpow(reg int x,reg int exp){
reg int res=1;
while(exp){
if(exp&1)
res=1ll*res*x%mod;
x=1ll*x*x%mod;
exp>>=1;
}
return res;
} int n;
ll x;
ll a[MAXN]; namespace Trie{
const int MAXSIZE=MAXN*50;
struct Node{
int ch[2];
int sum;
#define ch(x) unit[(x)].ch
#define sum(x) unit[(x)].sum
};
int tot;
Node unit[MAXSIZE];
inline void Init(void){
tot=1;
return;
}
inline void insert(reg ll x,reg int val){
reg int p=1;
for(reg int i=MAXLOG2A-1;i>=0;--i){
reg int c=(x>>i)&1;
if(!ch(p)[c])
ch(p)[c]=++tot;
sum(p)=add(sum(p),val);
p=ch(p)[c];
}
sum(p)=add(sum(p),val);
return;
}
inline int query(reg ll v){
reg int p=1;
reg int res=0;
for(reg int i=MAXLOG2A-1;i>=0;--i){
reg int cv=(v>>i)&1,cx=(x>>i)&1;
if(!cx)
res=add(res,sum(ch(p)[!cv]));
p=ch(p)[cx^cv];
}
if(p)
res=add(res,sum(p));
return res;
}
#undef ch
#undef sum
} int main(void){
n=read(),x=readll();
for(reg int i=0;i<n;++i)
a[i]=readll();
sort(a,a+n);
Trie::Init();
reg int ans=0;
for(reg int i=0;i<n;++i){
reg int val=add(1,Trie::query(a[i]));
Trie::insert(a[i],val);
ans=add(ans,val);
}
printf("%d\n",ans);
return 0;
}

「题解」300iq Contest 2 B Bitwise Xor的更多相关文章

  1. 「题解」300iq Contest 2 H. Honorable Mention

    本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目链接:gym102331H. 题意概述 给定一个长度为 \(n\) 的序列 \(a\),有 \(q\) 次询问,每次询问给定三个 ...

  2. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  3. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  4. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  5. 「题解」:[loj2763][JOI2013]现代豪宅

    问题 A: 现代豪宅 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...

  6. 「题解」:$Six$

    问题 A: Six 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...

  7. 「题解」:$Smooth$

    问题 A: Smooth 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...

  8. 「题解」:Kill

    问题 A: Kill 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...

  9. 「题解」:y

    问题 B: y 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...

随机推荐

  1. 简化mapstruct代码: mapstruct-spring-plus

    mapstruct MapStruct 是一个属性映射工具,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现.MapStruct官网地址: h ...

  2. Openstack 虚拟机宽带限速

    修改Neutron配置文件,使其支持Qos 修改Neutron.conf service_plugins = neutron.services.qos.qos_plugin.QoSPlugin 修改p ...

  3. ThinkPHP5.1 输出到模板HTML格式被强行转成了字符

    出现问题 控制器传给视图一个input标签,在视图页面显示出来就是 <input type='text'></input>,显示出来的是一个文本,而不是一个可以输入的文本框 解 ...

  4. ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule

    解释:执行docker-compose up -d时出现ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule 原因:防火墙 ...

  5. ZwQuerySystemInformation枚举内核模块

    在内核中通过调用此函数来枚举windows系统中已经加载的内核模块. NTSTATUS ZwQuerySystemInformation ( SYSTEM_INFORMATION_CLASS Syst ...

  6. Linux下的ARP攻击-断网

    1.软件工具安装 1. nmap --网络嗅探工具 2. dsniff ( arpspoof )    --ARP嗅探工具 3. net-tools ( ifconfig ) --网络工具 sudo ...

  7. Office·Word高级·VBA基础概念语法

    阅文时长 | 5.21分钟 字数统计 | 1823字符 『Office·Word高级·VBA基础概念语法』 编写人 | SCscHero 编写时间 | Monday, June 29, 2020 文章 ...

  8. [bug] Junit initializationError

    原因 导包错误 解决 先删除 import org.junit.Test; 再导入正确的包 参考 https://blog.csdn.net/javae100/article/details/7978 ...

  9. window 共享打印机

    https://www.zhihu.com/question/20653708 https://h30471.www3.hp.com/t5/da-yin-ji-yu-sao-miao-yi-de-an ...

  10. 利用stat指令查看文件创建时间

    -shroot@test-W330-C30:/# stat * 文件:'b' 大小:4096 块:8 IO 块:4096 目录设备:802h/2050d Inode:5636097 硬链接:2权限:( ...