题目要求合法的区间个数,这里考虑用总区间个数减去不合法的个数
假设某个数为区间最大值,那么包含这个数的最长区间内,所有数小于他并且所有数没有这个最大值没有的二进制位,可以按位考虑每个数(i)在(j)这一位上向左和向右第一个二进制位为1的位置,分别记为(l_{i,j},r_{i,j}),然后每个数再考虑所有二进制为0的位上的(l_{i,j},r_{i,j})区间的交集,左右端点为(ll,rr),那个这一位对答案加上((i-ll)*(rr-j))
要注意,前面可能有值相同的数,导致这次计算的(ll)包含了上次计算过的区间,这时候要让(ll)和(a_i)上次出现的位置取max
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define db double
#define eps (1e-8)
using namespace std;
const int N=200000+10;
il LL rd()
{
re LL x=0,w=1;re char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,a[N],l[N][33],r[N][33];
LL ans;
map<int,int> la;
int main()
{
n=rd();
for(int i=1;i<=n;i++) a[i]=rd();
for(int i=1;i<=n;i++)
for(int j=0;j<=32;j++)
l[i][j]=(a[i]&(1<<j))?i:l[i-1][j];
for(int j=0;j<=32;j++) r[n+1][j]=n+1;
for(int i=n;i>=1;i--)
for(int j=0;j<=32;j++)
r[i][j]=(a[i]&(1<<j))?i:r[i+1][j];
for(LL i=1;i<=n;i++)
{
LL ll=0,rr=n+1;
for(int j=0;j<=32;j++)
{
if(a[i]&(1<<j)) continue;
ll=max(ll,l[i][j]),rr=min(rr,r[i][j]);
}
ll=max(ll,la[a[i]]);
la[a[i]]=i;
ans+=(i-ll)*(rr-i);
}
printf("%lld
",1ll*n*(n+1)/2-ans);
return 0;
}