CodeForces - 875D High Cry

题面在这里!

 

    直接考虑每个位置成为最右边的最大值的位置,统计不合法区间,补集转化一下就好啦。

    复杂度O(N * 30)

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;

unordered_map<int,int> mmp;
int n,a[N],L[N],ex[35],ci[35];
ll ans=0;

int main(){
	ci[0]=1;
	for(int i=1;i<=30;i++) ci[i]=ci[i-1]<<1;
	
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",a+i);
		for(int j=0;j<=30;j++)
		    if(!(a[i]&ci[j])) L[i]=max(L[i],ex[j]);
		    else ex[j]=i;
	}
	
	fill(ex,ex+33,n+1);
	
	for(int i=n,R;i;i--){
		R=n+1;
		for(int j=0;j<=30;j++)
		    if(!(a[i]&ci[j])) R=min(R,ex[j]);
		    else ex[j]=i;
		if(mmp.count(a[i])) R=min(R,mmp[a[i]]);
		
		ans+=(R-i)*(ll)(i-L[i]);
		mmp[a[i]]=i;
	}
	
	printf("%lld\n",(n*(ll)(n+1)>>1)-ans);
	return 0;
	
}

  

posted @ 2018-07-13 10:55  蒟蒻JHY  阅读(218)  评论(0编辑  收藏  举报