这道题真的把我秀到了,我首先猜了一波结论,打了一个可持久化 \(\text{Trie}\) 加二分的两只 \(\log_2\) 的做法,发现不能 \(PP\) ,然后就一直改到比赛结束还没改过。

然后比完赛的时候改出来了,发现 \(WA\) \(on\) \(51\) ,心想好像比赛时改没改出来好像没什么区别啊。

然后就看了一波别人的题解,发现是一道结论题。。。

我是 \(sb\) 。

题解

你发现如果任意相邻的三个数中存在最高位相同,那么必然可以通过合并后两个来达到目的,也就证明了如果长度大于 \(60\) ,答案就必定为 \(1\) ,小于 \(60\) 的直接暴搜就可以了。

代码如下

可持久化 Trie

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],b[N];
struct Trie
{
int now,rt[N];
struct Node{int data,son[2];}tr[N<<5];
Trie(){now=0,memset(tr,0,sizeof(tr));}
void add(int u,int v,int x)
{
for(int i=30;i>=0;--i)
{
tr[v]=tr[u],tr[v].data++;
int tmp=(bool)(x&(1<<i));
tr[v].son[tmp]=++now;
u=tr[u].son[tmp],v=tr[v].son[tmp];
}
tr[v]=tr[u],tr[v].data++;
}
int query1(int u,int v,int x)
{
int res=0;
for(int i=30;i>=0;--i)
{
int tmp=(bool)(x&(1<<i));
int data=tr[tr[v].son[tmp^1]].data-tr[tr[u].son[tmp^1]].data;
if(data) u=tr[u].son[tmp^1],v=tr[v].son[tmp^1],res+=(1<<i);
else u=tr[u].son[tmp],v=tr[v].son[tmp];
}
return res;
}
int query2(int u,int v,int x)
{
int res=0;
for(int i=30;i>=0;--i)
{
int tmp=(bool)(x&(1<<i));
int data=tr[tr[v].son[tmp]].data-tr[tr[u].son[tmp]].data;
if(data) u=tr[u].son[tmp],v=tr[v].son[tmp];
else u=tr[u].son[tmp^1],v=tr[v].son[tmp^1],res+=(1<<i);
}
return res;
}
}t;
int main()
{
cin>>n;
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) b[i]=b[i-1]^a[i];
// for(int i=1;i<=n;++i) printf("%d ",b[i]);
// printf("\n");
t.rt[0]=++t.now;
for(int i=1;i<=n;++i)
{
t.rt[i]=++t.now;
t.add(t.rt[i-1],t.rt[i],b[i]);
}
int res=1e9+7;
for(int i=1;i<n;++i)
{
int l=1,r=i-1,tmp=-1;
while(l<=r)
{
int mid=(l+r)>>1;
int data=t.query1(t.rt[mid-1],t.rt[i-1],b[i]);
// printf("-------\n");
// printf("%d %d\n",mid,data);
if(data>a[i+1]) l=mid+1,tmp=mid;
else r=mid-1;
}
if(b[i]>a[i+1]&&tmp==-1) tmp=0;
// printf("---%d %d\n",i,tmp);
if(tmp>=0) res=min(res,i-tmp-1);
}
for(int i=2;i<=n;++i)
{
int l=i+1,r=n,tmp=-1;
while(l<=r)
{
int mid=(l+r)>>1;
int data=t.query2(t.rt[i],t.rt[mid],b[i-1]);
// printf("---%d %d\n",mid,data);
if(data<a[i-1]) r=mid-1,tmp=mid;
else l=mid+1;
}
if((b[n]^b[i-1])<a[i-1]&&tmp==-1) tmp=n;
// printf("%d\n",tmp);
if(tmp>=0) res=min(res,tmp-i);
}
if(res>=1e9+7) printf("-1\n");
else printf("%d\n",res);
return 0;
}

正解

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],b[N],res=1e9+7;
int main()
{
cin>>n;
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) b[i]=b[i-1]^a[i];
for(int i=1;i<n;++i)
{
for(int j=0;j<=32&&i-j>=1;++j)
{
for(int k=0;k<=32&&i+1+k<=n;++k)
if((b[i]^b[i-j-1])>(b[i]^b[i+1+k]))
res=min(res,j+k);
}
}
if(res>=1e9+7) printf("-1\n");
else printf("%d\n",res);
}

CF1457D XOR-gun的更多相关文章

  1. php获取汉字的拼音 拼音首字母

    /***获取汉字的拼音*/function pinyin($s, $isfirst = false) { static $pinyins; $s = trim($s); $len = strlen($ ...

  2. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  3. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  4. BZOJ 2115 【Wc2011】 Xor

    Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...

  5. xor和gates的专杀脚本

    前段时间的一次样本,需要给出专杀,应急中遇到的是linux中比较常见的两个家族gates和xor. 首先是xor的专杀脚本,xor样本查杀的时候需要注意的是样本的主进程和子进程相互保护(详见之前的xo ...

  6. Codeforces617 E . XOR and Favorite Number(莫队算法)

    XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: s ...

  7. Xor && 线性基练习

    #include <cstdio> #include <cstring> ; ; int cnt,Ans,b,x,n; inline int Max(int x,int y) ...

  8. BC之Claris and XOR

    http://acm.hdu.edu.cn/showproblem.php?pid=5661 Claris and XOR Time Limit: 2000/1000 MS (Java/Others) ...

  9. 异或链表(XOR linked list)

    异或链表(Xor Linked List)也是一种链式存储结构,它可以降低空间复杂度达到和双向链表一样目的,任何一个节点可以方便的访问它的前驱节点和后继结点.可以参阅wiki 普通的双向链表 clas ...

  10. hdu 5661 Claris and XOR

    Claris and XOR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

随机推荐

  1. linux基本操作之linux登陆

    一 文本登陆方式: 输入用户名与密码:/etc/passwd文件对照(口令文件,保存基本的用户信息):/etc/shadow文件对照(影子文件,保存密码信息):启动相应的shell程序:用户得到 一个 ...

  2. [LeetCode题解]21. 合并两个有序链表 | 递归

    解题思路 使用递归实现: 定义函数功能:合并两个有序链表,并返回链表的头 结束条件:两个链表其中一个为空,返回另一个链表 递推公式: l1.val < l2.val:l1.next = Merg ...

  3. 使用Feign发送HTTP请求

    使用Feign发送HTTP请求 在往常的 HTTP 调用中,一直都是使用的官方提供的 RestTemplate 来进行远程调用,该调用方式将组装代码冗余到正常业务代码中,不够优雅,因此在接触到 Fei ...

  4. 差点跪了!阿里3面真题:CAP和BASE理论了解么?可以结合实际案例说下不?

    本文节选自我开源的 JavaGuide :https://github.com/Snailclimb/JavaGuide (Github标星92k+!一份涵盖大部分 Java 程序员所需要掌握的核心知 ...

  5. Hbase启动报java异常

    在conf文件夹下的hbase-env.sh文件中的j添加ava_home的环境变量, ******************************************************** ...

  6. 网络系列之GET与POST请求方式的区别

    作为一枚正在学习前端的 小萌新,如果下面哪里有写的不对的话,可以帮我指出来吗,谢谢 1.是基于什么前提的?如果什么前提都没有,不使用任何规范,只考虑语法和理论上的HTTP协议 那么GET和POST几乎 ...

  7. 对Tarjan——有向图缩点算法的理解

    开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...

  8. C#中From窗体判断提示框是否

    int ret(变量名1) = command.ExecuteNonQuery(); if (ret(变量名1) > 0)//判断变量名是否大于0 { DialogResult dr(变量名2) ...

  9. Springboot结合Jpa的外键使用

    当我们写项目的时候,总有些奇奇怪怪的理由,非让你连表查询,其实最好的就是什么都不连,数据库完全解耦 但我们还是要学习下Jpa怎么根据外键查询 (这里说下Jpa+springboot的感觉,刚开始就感觉 ...

  10. LeetCode 027 Remove Element

    题目要求:Remove Element Given an array and a value, remove all instances of that value in place and retu ...