本地差一点,但是cf上过不去。
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10;
int n,root;
LL a[N];
int minl[N],minr[N],maxl[N],maxr[N];
struct carsedian {
int lson,rson;
int maxn,minn;
}tr_car[N];
stack<int> st;
vector<int> g[100];
char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline LL read() {
LL x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x*f;
}
inline MAX(int a,int b) {
return a>b?a:b;
}
inline MIN(int a,int b) {
return a<b?a:b;
}
inline int popcount(LL x) {
int cnt=0;
while(x) {cnt++; x-=x&(-x);}
return cnt;
}
inline void dfs(int nd) {
if(!nd) return ;
tr_car[nd].maxn=tr_car[nd].minn=nd;
dfs(tr_car[nd].lson); dfs(tr_car[nd].rson);
if(tr_car[nd].lson) {
tr_car[nd].maxn=MAX(tr_car[nd].maxn,tr_car[tr_car[nd].lson].maxn);
tr_car[nd].minn=MIN(tr_car[nd].minn,tr_car[tr_car[nd].lson].minn);
}
if(tr_car[nd].rson) {
tr_car[nd].maxn=MAX(tr_car[nd].maxn,tr_car[tr_car[nd].rson].maxn);
tr_car[nd].minn=MIN(tr_car[nd].minn,tr_car[tr_car[nd].rson].minn);
}
}
struct segment {
int cnt1,cnt2,siz,tot1,tot2;
}tr[N*4];
int m,b[N*3];
inline void pushup(int nd,int l,int r) {
if(tr[nd].cnt1) tr[nd].tot1=b[r+1]-b[l];
else if(l!=r) tr[nd].tot1=tr[nd<<1].tot1+tr[nd<<1|1].tot1;
else tr[nd].tot1=0;
if(tr[nd].cnt2) tr[nd].tot2=b[r+1]-b[l];
else if(l!=r) tr[nd].tot2=tr[nd<<1].tot2+tr[nd<<1|1].tot2;
else tr[nd].tot2=0;
if(tr[nd].cnt1&&tr[nd].cnt2) tr[nd].siz=b[r+1]-b[l];
else if(tr[nd].cnt1&&tr[nd].tot2) tr[nd].siz=tr[nd].tot2;
else if(tr[nd].cnt2&&tr[nd].tot1) tr[nd].siz=tr[nd].tot1;
else if(l!=r) tr[nd].siz=tr[nd<<1].siz+tr[nd<<1|1].siz;
else tr[nd].siz=0;
}
inline void modify(int nd,int l,int r,int x,int y,int k,int opt) {
if(r<x||l>y) return ;
if(l>=x&&r<=y) {
if(opt==1) tr[nd].cnt1+=k;
else tr[nd].cnt2+=k;
pushup(nd,l,r);
return ;
}
int mid=l+r>>1;
modify(nd<<1,l,mid,x,y,k,opt);
modify(nd<<1|1,mid+1,r,x,y,k,opt);
pushup(nd,l,r);
}
int cnt_que;
struct node {
int x,ya,yb,k,opt;
}que[4*N];
inline int cmp(node x,node y) {
if(x.x!=y.x) return x.x<y.x;
else return x.k<y.k;
}
inline int find(int x) {
return lower_bound(b+1,b+1+m,x)-b;
}
int main() {
freopen("a.in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++) {
a[i]=read();
g[popcount(a[i])].push_back(i);
}
for(int i=1;i<=n;i++) {
int lst=0;
while(st.size()&&a[i]<a[st.top()]) {lst=st.top(); st.pop();}
if(!st.size()) root=i;
else tr_car[st.top()].rson=i;
tr_car[i].lson=lst;
st.push(i);
}
dfs(root);
for(int i=1;i<=n;i++) {
minl[i]=tr_car[i].minn; minr[i]=tr_car[i].maxn;
tr_car[i].lson=tr_car[i].maxn=tr_car[i].minn=tr_car[i].rson=0;
}
while(st.size()) st.pop();
for(int i=1;i<=n;i++) {
int lst=0;
while(st.size()&&a[i]>a[st.top()]) {lst=st.top(); st.pop();}
if(!st.size()) root=i;
else tr_car[st.top()].rson=i;
tr_car[i].lson=lst;
st.push(i);
}
dfs(root);
for(int i=1;i<=n;i++) {
maxl[i]=tr_car[i].minn; maxr[i]=tr_car[i].maxn;
}
LL sum=0;
for(int zyz=0;zyz<=60;zyz++) {
m=0;
for(int t:g[zyz]) {
int l1=minl[t],r1=minr[t];
int l2=maxl[t],r2=maxr[t];
que[++cnt_que]={l1-1,t-1,r1,+1,1};
que[++cnt_que]={t,t-1,r1,-1,1};
que[++cnt_que]={l2-1,t-1,r2,+1,2};
que[++cnt_que]={t,t-1,r2,-1,2};
b[++m]=t-1; b[++m]=r2; b[++m]=r1;
}
sort(b+1,b+1+m);
m=unique(b+1,b+1+m)-b-1;
sort(que+1,que+1+cnt_que,cmp);
for(int i=1;i<=cnt_que;i++) {
if(i>1) sum+=(LL)(que[i].x-que[i-1].x)*tr[1].siz;
modify(1,1,m,find(que[i].ya),find(que[i].yb)-1,que[i].k,que[i].opt);
}
cnt_que=0;
}
cout<<sum<<endl;
return 0;
}
/*
*/