「题解」300iq Contest 2 B Bitwise Xor
本文将同步发布于:
题目
题目链接: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\) 结尾的最长的合法子序列,那么有转移方程:
\]
时间复杂度为 \(\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的更多相关文章
- 「题解」300iq Contest 2 H. Honorable Mention
本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目链接:gym102331H. 题意概述 给定一个长度为 \(n\) 的序列 \(a\),有 \(q\) 次询问,每次询问给定三个 ...
- 「题解」「美团 CodeM 资格赛」跳格子
目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...
- 「题解」「HNOI2013」切糕
文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...
- 「题解」JOIOI 王国
「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...
- 「题解」:[loj2763][JOI2013]现代豪宅
问题 A: 现代豪宅 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...
- 「题解」:$Six$
问题 A: Six 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...
- 「题解」:$Smooth$
问题 A: Smooth 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...
- 「题解」:Kill
问题 A: Kill 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...
- 「题解」:y
问题 B: y 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...
随机推荐
- XCTF-i-get-id-200
i-get-id-200 题目描述 嗯..我刚建好了一个网站 解题过程 一共有三个页面 Hello World 告诉了页面是perl写的 Forms 输入name和age会返回渲染后的字符串 搜了一下 ...
- 公网IP和私有IP的区别和用途
在Internet网络上有上千百万台主机,为了能够将这些主机区分开来,于是就给每台主机都分别配了一个专门的地址,称为IP地址. 通过IP地址就可以访问到每一台主机.IP地址由4部分数字组成,ghost ...
- 21.Quick QML-FileDialog、FolderDialog对话框
1.FileDialog介绍 Qt Quick中的FileDialog文件对话框支持的平台有: 笔者使用的是Qt 5.8以上的版本,模块是import Qt.labs.platform 1.1. 它的 ...
- IO系列测试源码
//IO系列测试源码(需要自取) using System; using System.CodeDom; using System.Collections.Generic; using System. ...
- Day015 异常处理机制
异常处理机制 抛出异常 捕获异常 异常处理的五个关键字 try:监控一个代码块,有异常就能通过catch捕获 catch(想要捕获的异常类型):捕获想要捕获的异常,catch代码块的代码只有在捕获到异 ...
- training11.14
7-10 关于堆的判断 (25分) 题目:将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: x is the root:x是根结点: x and ...
- 【开源技术分享】无需流媒体服务,让浏览器直接播放rtsp/rtmp的神器:EasyMedia
不同于市面上其他需要各种转发到流媒体服务的中间件来说,EasyMedia不需要依赖任何nginx-rtmp,srs,zlmediakit等等第三方流媒体服务,只需要你有rtsp或者rtmp等等协议的视 ...
- ES6中的展开运算符和解构对象
let obj = { a:1 b:2 } let obj2 = { ...obj c:3 d:4 } console.log(obj2)//1,2,3,4,对象展开 //常考题目 let a = 1 ...
- [Java] Spring 原理
IOC(Inverse of Control)控制反转 依赖对象的获得被反转了,由自己创建变为从IOC容器获取 优点 代码更简介,不需要new对象 面向接口编程,使用者与具体类解耦,易扩展 方便进行A ...
- 使用 dd 命令进行硬盘 I/O 性能检测
使用 dd 命令进行硬盘 I/O 性能检测 作者: Vivek Gite 译者: LCTT DongShuaike | 2015-08-28 07:30 评论: 1 收藏: 6 如何使用dd命令测 ...