Codeforces 876F High Cry【逆向思维】

来源:互联网 发布:南开大学网络教学平台 编辑:程序博客网 时间:2024/05/22 04:51

参考:http://blog.csdn.net/mengxiang000000/article/details/78261348

题目大意:让我们计算有多少个区间【L,R】,使得其或的和严格大于区间内所有的数。
#include <bits/stdc++.h>using namespace std;#define N 200050#define LL long long #define up 32LL n;map<int,int>last;int a[N];int L[N],R[N],pos[N];int main(){    scanf("%lld",&n);    for(int i=1;i<=n;++i)scanf("%d",&a[i]);    for(int i=1;i<=n;++i){        L[i]=last[a[i]];        for(int j=0;j<up;++j){            if(!(a[i]&(1<<j)))L[i]=max(L[i],pos[j]);        }        for(int j=0;j<up;++j){            if((a[i]&(1<<j)))pos[j]=i;        }        last[a[i]]=i;    }    for(int j=0;j<up;++j)pos[j]=n+1;    for(int i=n;i>=1;--i){        R[i]=n+1;        for(int j=0;j<up;++j)            if(!(a[i]&(1<<j)))R[i]=min(R[i],pos[j]);        for(int j=0;j<up;++j)            if(a[i]&(1<<j))pos[j]=i;    }    LL sum=(1LL*n*(n+1))/2;    for(int i=1;i<=n;++i){        LL t1=i-L[i];        LL t2=R[i]-i;        sum-=t1*t2;    }    printf("%lld\n",sum);}