早知道先看D题就不会掉这么惨了
枚举左端点,那么区间或值最多变化log次
二分变化的区间,再二分区间或值大于区间最大值的区间
用ST表记一下区间最大值、或值
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int N=200010;
int n,a[N],lg2[N];
int ior[N][20],imax[N][20];
inline void Pre(){
for(int i=1;i<=n;i++) lg2[i]=lg2[i-1]+((1<<lg2[i-1]+1)==i);
int t=lg2[n];
for(int i=1;i<=n;i++) ior[i][0]=imax[i][0]=a[i];
for(int k=1;k<=t;k++)
for(int i=1;i+(1<<k)-1<=n;i++)
ior[i][k]=ior[i][k-1]|ior[i+(1<<k-1)][k-1],imax[i][k]=max(imax[i][k-1],imax[i+(1<<k-1)][k-1]);
}
inline int Qor(int l,int r){
int t=lg2[r-l+1];
return ior[l][t]|ior[r+1-(1<<t)][t];
}
inline int Qmax(int l,int r){
int t=lg2[r-l+1];
return max(imax[l][t],imax[r-(1<<t)+1][t]);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
Pre(); ll ans=0;
for(int i=1;i<=n;i++){
int cur=a[i],j=i;
while(j<=n){
int l=j,r=n,mid,nxt;
while(l<=r) Qor(i,mid=l+r>>1)==cur?l=(nxt=mid)+1:r=mid-1;
l=j; r=nxt; int pos=-1;
while(l<=r) Qmax(i,mid=l+r>>1)<cur?l=(pos=mid)+1:r=mid-1;
if(~pos) ans+=pos-j+1;
j=nxt+1; cur=Qor(i,j);
}
}
cout<<ans<<endl;
return 0;
}