求助卡常
查看原帖
求助卡常
926650
Oracle_zyz楼主2023/8/26 22:55

本地差一点,但是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;
}
/*
*/
2023/8/26 22:55
加载中...