1. 程式人生 > 其它 >E. Bored Bakry 題解(二進位制+思維)

E. Bored Bakry 題解(二進位制+思維)

題目連結

題目思路

第一眼以為是二分,但是發現倒了

那麼就肯定是和二進位制有關

其實差不多能發現性質

就是必須為偶數,並且這個區間的第k位二進位制全部為1,且位數大於k位的二進位制數,異或起來都為0就行

但是感覺寫起來沒那麼簡單,看了一下一個大佬的寫法,一下就解決了

我的複雜度多了一個log,其實可以不用map,但是我懶。。

程式碼

#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e6+5,inf=(1ll<<31)-1,mod=1e9+7;
const double eps=1e-6;
int n;
int a[maxn];
vector<int> tmp;
int cal(){
    int len=0,val=0;
    map<int,int> mp1,mp2;
    mp2[0]=0;
    // 一個放奇數,一個放偶數
    for(int i=0;i<tmp.size();i++){
        val^=tmp[i];
        if(i%2==0){
            if(mp1.count(val)){
                len=max(len,i+1-mp1[val]);
            }
            if(!mp1.count(val)){
                mp1[val]=i+1;
            }
        }else{
            if(mp2.count(val)){
                len=max(len,i+1-mp2[val]);
            }
            if(!mp2.count(val)){
                mp2[val]=i+1;
            }
        }

    }
    return len;
}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int num=0,ans=0;
    for(int i=20;i>=0;i--){
        num+=(1<<i);
        for(int j=1;j<=n;j++){
            if(a[j]&(1<<i)){
                tmp.push_back(a[j]&num);
            }else{
                ans=max(ans,cal());
                tmp.clear();
            }
        }
        ans=max(ans,cal());
        tmp.clear();
    }
    printf("%d\n",ans);
    return 0;
}

不擺爛了,寫題