• Codeforces Round #687 (Div. 2, based on Technocup 2021 Elimination Round 2) D. XOR-gun (二进制,异或,前缀和)


    • 题意:给你一组非递减的数,你可以对两个连续的数进行异或,使其合并为一个数,问最少操作多少次使得这组数不满足非递减.
    • 题解:首先,给出的这组数是非递减的,我们考虑二进制,对于三个连续的非递减的最高位相同的数,我们可以将后面的两个异或,那么第一个数一定比合并的数大,所以当出现三个最高位相同的数时,操作数一定是(1),题目所给的(a_i)的最大值是(1e9),所以最多是(2^{30}),也就对应着(30)个最高位的情况,而当出现三个最高位相同的情况时操作数为(1),所以每个最高位的情况最多只能有(2)种,也就是(n)最多有(59)个((1)的最高位对应的情况只有一种),所以当(nge 60)的时候我们直接输出(1)即可,否则可以用前缀和记录异或情况然后(O(n^4))暴力枚举所有情况求最小值.
    • 代码:
    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
     
    int n;
    int a[N],pre[N];
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	cin>>n;
     
    	rep(i,1,n){
    		cin>>a[i];
    		pre[i]=a[i];
    	}
     
    	if(n>=60) {cout<<1<<'
    ';return 0;}
     
    	rep(i,2,n) pre[i]=pre[i-1]^a[i];
     
    	int ans=INF;
     
    	rep(i,1,n){
    		rep(j,i,n){
    			rep(k,j+1,n){
    				rep(p,k,n){
    					if((pre[j]^pre[i-1])>(pre[p]^pre[k-1])){
    						ans=min(ans,j-i+p-k);
    					}
    				}
    			}
    		}
    	}
    	if(ans==INF) ans=-1;	
    	cout<<ans<<'
    ';
    	
        return 0;
    }
    
  • 相关阅读:
    阻止事件冒泡和默认行为,禁止键盘事件
    jquery移除、绑定、触发元素事件
    HTML`CSS_网站页面不同浏览器兼容性问题解决
    computed属性与methods、watched
    call()方法和apply()方法用法总结
    push()、shift()与pop()、unshift()、splice()
    vue指令总结
    fieldset标签
    mysql存储过程定义者
    数据库死锁
  • 原文地址:https://www.cnblogs.com/lr599909928/p/14059174.html
Copyright © 2020-2023  润新知