题目链接:D 小A的位运算
自己做题的时候想着输入时求出或的总和,然后挨个枚举不选的那个数。但是位运算在某一位上可能有多个1,总和sum减去那个数不是正解,然后就又没啥思路了。
看完标程后发现自己对前缀和、后缀和的理解还不够。这个“和”并不一定指的是加法,可以是所有的累加性质的运算,比如加、乘、或等等(别的还没想到,希望有大神补充一下)。
对于某一位i来说,前缀和L[i]与后缀和R[I]的和 L[i]+R[i]等于sum+a[i] (a[i]在L和R中被重复计算了),而L[i-1]+R[i+1]==sum-a[i]。前面两个式子的“+”可以指代有累加性质的运算,而“-”是其逆运算。
放在这个题里,刚好L[i-1]+R[i+1]就等于除了a[i]以外的数字都被或上了,然后就剩下枚举。
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=5e6+10;
ll a[maxn];
ll l[maxn];
ll r[maxn];
int main(){
int n;
ll ans=0;
cin>>n;
for(int i = 0 ; i < n ; i ++) cin>>a[i];
for(int i = 0 ; i < n ; i ++) l[i]=l[i-1]|a[i];
for(int i = n-1 ; i >= 0 ; i--) r[i]=r[i+1]|a[i];
for(int i = 0 ; i < n ; i ++) ans=max(ans,r[i+1]|l[i-1]);
cout<<ans;
return 0;
}