题解:P17723 [SCP-S 2026] 函数 / func
推荐来做观察相似的 Another Bitwise Interactive Problem。
尊重题目,题解中用
考虑什么时候
注意到这当且仅当
所以做完了,我们先算出所有区间的或和,这个是经典题目,拆位,遍历右端点
根据上面的结论,枚举
时间复杂度
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const int N=2e6+5;
ull ans;
int n,a[N];
int lst[N],cnt[N],nxt[N];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
for(int j=0;j<30;j++) if(a[i]>>j&1) lst[j]=i;
for(int j=0;j<30;j++) ans+=(1ll<<j)*lst[j];
}
for(int j=0;j<21;j++){
int r=0,c=(1<<j);
nxt[n+1]=n+1;
for(int i=n;i>=1;i--){
if(a[i]>>j&1) nxt[i]=i;
else nxt[i]=nxt[i+1];
}
for(int i=1;i<=n;i++){
while(1){
if(!c) break;
if(r==n) break;
r++;
if(a[r]<(1<<j)){
if(!cnt[a[r]]) c--;
cnt[a[r]]++;
}
if(a[r]&(1<<j)){
for(int k=i;k<=r;k++) if(a[k]<(1<<j)) cnt[a[k]]=0;
c=(1<<j);
i=r;
break;
}
}
if(!c) ans+=(nxt[r]-r)*(1ll<<j);
if(a[i]<(1<<j)&&cnt[a[i]]){
cnt[a[i]]--;
if(!cnt[a[i]]) c++;
}
}
}
cout<<ans;
return 0;
}