zoukankan      html  css  js  c++  java
  • 【Codeforces】Technocup 2021

    Technocup 2021 - Elimination Round 2 D. XOR-gun

    题意

    给出一个长度为 (n) 非递减的序列 (a),现在可以执行以下操作一次或者多次:

    选择两个相邻的数字将他们删去,并在此位置添加他们的异或和。

    问最少需要多少次操作使得,序列不是非递减的。

    题解

    定义 (h_i)(a_i) 的最高位下标。

    因为序列是非递减,可知 : (h_i leq h_{i+1})

    如果存在 (h_{i-1} = h_i =h_{i+1}) ,就可以选择一次操作,将 (a_i)(a_{i+1}) 异或。

    这样就满足 (a_{i-1} > a_{i})

    因为 (h_ileq h_{i+1})(a_ileq 10^9) ,(h_i) 最大为 (30)

    所以只要 (n >60) 一定会存在连续三个数字的最高位相等。

    (nleq 60) 时,我们可以暴力枚举。

    操作区间 ([l,m])([m+1,r]) 使得,(a_l > a_{l+1})

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #define pb push_back
    typedef long long ll;
    typedef unsigned long long ull;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    const int seed=233;
    const int N=1e5+10;
    
    int arr[N],brr[N];
    int get(int l,int r)
    {
        return brr[l-1]^brr[r];
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&arr[i]);
            brr[i]=brr[i-1]^arr[i];
        }
        if(n>60){
            printf("1
    ");
            return 0;
        }
        int ans=inf;
        for(int i=1;i<=n;i++){
            for(int j=i;j<n;j++){
                int pre=get(i,j);
                for(int k=j+1;k<=n;k++){
                    if(get(j+1,k)<pre){
                        ans=min(ans,k-i-1);
                    }
                }
            }
        }
        if(ans==inf){
            printf("-1
    ");
        }else{
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    NOI 2016 区间 解题报告
    有关莫队
    [JSOI2008]最大数 线段树解法
    HDU P3341 Lost's revenge 题解+数据生成器
    BZOJ P1212 [HNOI2004] L语言
    洛谷P3168 [CQOI2015]任务查询系统
    普通平衡树Tyvj1728、luogu P3369 (splay)
    洛谷P3384 树链剖分
    BZOJ P2157 旅游
    【算法导论】第6章,堆排序
  • 原文地址:https://www.cnblogs.com/valk3/p/14066809.html
Copyright © 2011-2022 走看看