CF1457D XOR-gun
这道题真的把我秀到了,我首先猜了一波结论,打了一个可持久化 \(\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的更多相关文章
- php获取汉字的拼音 拼音首字母
/***获取汉字的拼音*/function pinyin($s, $isfirst = false) { static $pinyins; $s = trim($s); $len = strlen($ ...
- [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 ...
- 二分+DP+Trie HDOJ 5715 XOR 游戏
题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- BZOJ 2115 【Wc2011】 Xor
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...
- xor和gates的专杀脚本
前段时间的一次样本,需要给出专杀,应急中遇到的是linux中比较常见的两个家族gates和xor. 首先是xor的专杀脚本,xor样本查杀的时候需要注意的是样本的主进程和子进程相互保护(详见之前的xo ...
- Codeforces617 E . XOR and Favorite Number(莫队算法)
XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: s ...
- Xor && 线性基练习
#include <cstdio> #include <cstring> ; ; int cnt,Ans,b,x,n; inline int Max(int x,int y) ...
- BC之Claris and XOR
http://acm.hdu.edu.cn/showproblem.php?pid=5661 Claris and XOR Time Limit: 2000/1000 MS (Java/Others) ...
- 异或链表(XOR linked list)
异或链表(Xor Linked List)也是一种链式存储结构,它可以降低空间复杂度达到和双向链表一样目的,任何一个节点可以方便的访问它的前驱节点和后继结点.可以参阅wiki 普通的双向链表 clas ...
- hdu 5661 Claris and XOR
Claris and XOR Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
随机推荐
- linux基本操作之linux登陆
一 文本登陆方式: 输入用户名与密码:/etc/passwd文件对照(口令文件,保存基本的用户信息):/etc/shadow文件对照(影子文件,保存密码信息):启动相应的shell程序:用户得到 一个 ...
- [LeetCode题解]21. 合并两个有序链表 | 递归
解题思路 使用递归实现: 定义函数功能:合并两个有序链表,并返回链表的头 结束条件:两个链表其中一个为空,返回另一个链表 递推公式: l1.val < l2.val:l1.next = Merg ...
- 使用Feign发送HTTP请求
使用Feign发送HTTP请求 在往常的 HTTP 调用中,一直都是使用的官方提供的 RestTemplate 来进行远程调用,该调用方式将组装代码冗余到正常业务代码中,不够优雅,因此在接触到 Fei ...
- 差点跪了!阿里3面真题:CAP和BASE理论了解么?可以结合实际案例说下不?
本文节选自我开源的 JavaGuide :https://github.com/Snailclimb/JavaGuide (Github标星92k+!一份涵盖大部分 Java 程序员所需要掌握的核心知 ...
- Hbase启动报java异常
在conf文件夹下的hbase-env.sh文件中的j添加ava_home的环境变量, ******************************************************** ...
- 网络系列之GET与POST请求方式的区别
作为一枚正在学习前端的 小萌新,如果下面哪里有写的不对的话,可以帮我指出来吗,谢谢 1.是基于什么前提的?如果什么前提都没有,不使用任何规范,只考虑语法和理论上的HTTP协议 那么GET和POST几乎 ...
- 对Tarjan——有向图缩点算法的理解
开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...
- C#中From窗体判断提示框是否
int ret(变量名1) = command.ExecuteNonQuery(); if (ret(变量名1) > 0)//判断变量名是否大于0 { DialogResult dr(变量名2) ...
- Springboot结合Jpa的外键使用
当我们写项目的时候,总有些奇奇怪怪的理由,非让你连表查询,其实最好的就是什么都不连,数据库完全解耦 但我们还是要学习下Jpa怎么根据外键查询 (这里说下Jpa+springboot的感觉,刚开始就感觉 ...
- LeetCode 027 Remove Element
题目要求:Remove Element Given an array and a value, remove all instances of that value in place and retu ...