D. XOR-gun(思维+前缀异或+暴力)

98 篇文章 3 订阅
40 篇文章 0 订阅
本文解析了Codeforces竞赛中的D问题,涉及连续三位数异或操作的优化策略。通过构造和剪枝,核心思路是利用序列中连续高位一致的特性找到最优解,最终将范围限制在60以下。主要讨论了两种异或操作场景:区间异或和连续区间的合并异或。
摘要由CSDN通过智能技术生成

https://codeforces.com/contest/1457/problem/D


话说这场D吃完饭hack了400+人。

思路:开始看到以为答案只有-1,1,2三种,但是并不是。

构造发现如果连续三位的最高位1位置一样,那么就能1次达到目的。

那么这种情况下的极限是什么呢?

0001

0010

0011

01??

01??

1???

1???

可以看到,在最大值1e9的情况下,当序列里刚好不冲突的时候,有60个数字。剩下进去就必然可以1次。

那么题目就剪枝到60以下了。

考虑两个情况:一个是一个区间直接异或出来波峰或者波谷。(n^2)

另一个是两个连续区间分别异或再合并出来的情况。(n^3)

 

代码上设置边界a[n+1]=1e18;

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=100;
typedef long long LL;
LL a[maxn];
LL sum[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  if(n>60){
    cout<<"1"<<endl;
    return 0;
  }
  a[n+1]=1e18;
  for(LL i=1;i<=n;i++) cin>>a[i];
  for(LL i=1;i<=n;i++){
    sum[i]=sum[i-1]^a[i];
  }
  LL res=1e18;
  for(LL l=1;l<=n;l++){
    for(LL r=l+1;r<=n;r++){
        LL t=sum[r]^sum[l-1];
        if(t>a[r+1]||t<a[l-1]){
            res=min(res,r-l+1-1);
          ///  debug(res);
        }
    }
  }
  for(LL i=1;i<=n;i++){///[i,j][j+1,k]
    for(LL j=i+1;j<=n;j++){
        for(LL k=j+1;k<=n;k++){
            LL t1=sum[j]^sum[i-1];
            LL t2=sum[k]^sum[j];
            if(t1>t2){
                res=min(res,k-j+1-1+j-i+1-1-1);
            }
        }
    }
  }
  if(res==1e18){
    cout<<"-1"<<endl;
  }
  else cout<<res<<endl;
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值