Problem Author: | Hadi Takla (TaklaOI) |
Prepared by: | Hadi Takla (TaklaOI) |
Edited by: | Hadi Takla (TaklaOI) |
Solution
First , let's simplify the given operation.
when we take a range , first we set x = a_l \& a_{l+1} \& ... \& a_r , which means that contains only common bits in the range (l,r) , so when we replace each element a_i in the range by a_i \oplus x , we are turning off the common bits in the range.
now we need to minimize the bitwise or of the array.
suppose we need to turn off a bit in the or , it means that we should turn off all occurrences of the bit in the array .
now , let be the first index where the bit is turned on , is the last index where the bit is turned on.
we can turn the bit off in the final answer if and only if the bit is common in range (fr[i] , lst[i]), why ?
since is the first index where the bit is turned on , and is the last index where the bit is turned on , so any range () where l < fr[i] or r > lst[i] won't has the bit as a common bit.
and any range (l , r) where l > fr[i] or r < lst[i] won't affect the final answer value.
so the only candidate range is fr[i] , lst[i].
we can iterate over all bits , and for each bit try to apply the operation on fr[i] , lst[i] , then take the minimum answer.
Time complexity : \mathcal{O}(30 \cdot n).
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define F first
#define S second
using namespace std;
const int N = 2e5 + 1;
const int M = 1e9 + 7;
signed main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tc = 1;
cin>>tc;
while(tc--)
{
int n;
cin>>n;
int a[n+1] , ans = 0;
for(int i=1;i<=n;i++){
cin>>a[i];
ans |= a[i];
}
int fr[32]={0},lst[32]={0};
for(int i=1;i<=n;i++)
{
for(int j=0;j<=30;j++)
{
if(a[i] & (1LL<<j))
lst[j] = i;
}
}
for(int i=n;i>=1;i--)
{
for(int j=0;j<=30;j++)
{
if(a[i] & (1LL<<j))
fr[j] = i;
}
}
for(int j=0;j<=30;j++)
{
int x = (1LL<<31)-1;
for(int i=fr[j];i<=lst[j];i++)
x &= a[i];
for(int i=fr[j];i<=lst[j];i++)
a[i] ^= x;
int cur = 0;
for(int i=1;i<=n;i++)
cur |= a[i];
for(int i=fr[j];i<=lst[j];i++)
a[i] ^= x;
ans = min(ans , cur);
}
cout<<ans<<endl;
}
}