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;
    }
    
  • 相关阅读:
    斐波那契数列
    用两个栈实现队列
    从尾到头打印链表
    HDOJ5877(dfs序+离散化+树状数组)
    HDOJ5876(补图的最短路)
    POJ3090(欧拉函数)
    POJ2478(欧拉函数)
    POJ2407(欧拉函数)
    POJ2142(扩展欧几里得)
    POJ3020(最小边覆盖)
  • 原文地址:https://www.cnblogs.com/valk3/p/14066809.html
Copyright © 2011-2022 走看看