【CS Round 34】Max Or Subarray

Keywords: iOS

[Title link] https://csacademy.com/contest/round-34/summary/

[title]

Let you find the shortest continuous substring;
Make all the numbers or in this substring the largest;

[Abstract]

For each starting point i;
The maximum value must be all or i n the section i.n.
It's just that the length may be a little shorter.
Moreover, it is monotonous.
Define a right endpoint;
Obviously, you can dichotomize the right endpoint.
The farther the right end is, the bigger the or of the right end is.
Because the number of 1 will not decline.
Processing the prefix sum of the number of the first i digits, all the binary digits in one digit; (30 digits)

[Number Of WA]

1

[introspection]

At first, we didn't notice that it was zero.
The length of the initial answer should be set to + oo.

[Complete code]

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100;

LL g[N][40],a[N],two[40],temp[40],tma = 0,tlen = N;
int n;

int main(){
    //Open();
    Close();
    cin >> n;
    two[0] = 1;
    rep1(i,1,30)
        two[i] = two[i-1]*2;
    rep1(i,1,n) cin >> a[i];
    rep1(i,1,n){
        rep1(j,0,29){
            g[i][j] = g[i-1][j];
            if ( two[j] & a[i]){
                g[i][j]++;
            }
        }
    }
    rep1(i,1,n){
        LL ma = 0;
        rep1(j,0,29){
            temp[j] = g[n][j]-g[i-1][j];
            if (temp[j])
                ma+=two[j];
        }
        int l = i,r = n,idx = n;
        while (l <= r){
            int mid = (l+r)>>1;
            LL tt = 0;
            rep1(j,0,29){
                temp[j] = g[mid][j]-g[i-1][j];
                if (temp[j])
                    tt+=two[j];
            }
            if (tt < ma){
                l = mid + 1;
            }else{
                idx = mid;
                r = mid - 1;
            }
        }
        if (ma>tma){
            tma = ma,tlen = idx-i+1;
        }
        else
            if (ma==tma && tlen > idx-i+1){
                tlen = idx-i+1;
            }
    }
    //cout << tma << endl;
    cout << tlen << endl;
    return 0;
}

Posted by deerly on Mon, 11 Feb 2019 17:39:17 -0800