本文将同步发布于:

题目

题目链接: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. 绕过网站WAF(图片绕过)

    当我们在渗透一个网站的时候,很多时候,会遇到下面这种情况.网站装有WAF,把我们的SQL注入语句给拦截了. 这就是网站的安全狗 此时,我们的渗透会陷入僵局.到底应该如何才能让我们的语句绕过安全狗的检查 ...

  2. 【js】Leetcode每日一题-停在原地的方案数

    [js]Leetcode每日一题-停在原地的方案数 [题目描述] 有一个长度为 arrLen 的数组,开始有一个指针在索引 0 处. 每一步操作中,你可以将指针向左或向右移动 1 步,或者停在原地(指 ...

  3. 【Spring浅析】一、 BeanFactory 有啥可说的?

    阅读 Spring 源码,BeanFactory 是避不了的存在.而大家常见的使用场景,也是以下形式: ConfigurableApplicationContext ctx = SpringAppli ...

  4. OO_Unit1_表达式求导

    CSDN链接 一.第一次作业 1.需求分析 简单多项式导函数 带符号整数 支持前导0的带符号整数,符号可省略,如: +02.-16.19260817等. 幂函数 一般形式 由自变量x和指数组成,指数为 ...

  5. 新代(Syntec)机床的IP设置

    一.前言 通过以太网来做机床联网数据采集时,第一步通常是设置机床的IP和找网口 二.机床IP如何设置? 步骤一.找到设置IP的界面 [维护]>[网络设定] 步骤二.设置IP 设定[IP地址取得方 ...

  6. 放弃模拟器,安卓手机WiFi投屏到Ubuntu

    曾经使用过一些安卓的模拟器,但是特别占用资源,而且很多平时使用的非游戏生活类App都有兼容性问题,自然最终无奈而放弃了. 现在将学习环境迁移到了Ubuntu平台,发现各个方面还是不错的,平时使用的各种 ...

  7. CentOS 7 设置日期和时间 timedatectl

    CentOS 7 设置日期和时间 在CentOS 6版本,时间设置有date.hwclock命令,从CentOS 7开始,使用了一个新的命令timedatectl. timedatectl [root ...

  8. 3.1.5 LTP(Linux Test Project)学习(五)-LTP代码学习

    3.1.5 LTP(Linux Test Project)学习(五)-LTP代码学习 Hello小崔 ​ 华为技术有限公司 Linux内核开发 2 人赞同了该文章 LTP代码学习方法主要介绍两个步骤, ...

  9. 攻防世界(十一)warmup

    攻防世界系列 :warmup 1.打开题目,一个贱贱的滑稽表情 F12看到注释内容source.php 2.访问source.php <?php highlight_file(__FILE__) ...

  10. BogoMips 和cpu主频无关 不等于cpu频率

    http://tinylab.org/explore-linux-bogomips/ 内核探索:Linux BogoMips 探秘 Tao HongLiang 创作于 2015/05/12 打赏 By ...