首页 > 其他 > 详细

前缀后缀——cf1167E

时间:2019-05-16 14:20:12      阅读:183      评论:0      收藏:0      [点我收藏+]

想了很久没弄明白,对于边界的情况还是有问题

等题解出了再看看

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 1000000 + 10;
int n,x,a[N];
int L[N],R[N];
int pre[N],suf[N];

int main() {
    for(int i=0;i<N;i++){
        L[i]=N,R[i]=0;
    }
    scanf("%d%d",&n,&x);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        L[a[i]]=min(L[a[i]],i);
        R[a[i]]=max(R[a[i]],i);
    }

    int prelen=0,suflen=x+1;
    for(int i=1;i<=x;i++){
        if(R[i]==0)
            pre[++prelen]=pre[prelen-1];
        else {
            if(L[i]>pre[prelen]) 
                pre[++prelen]=R[i]; 
            else break;
        }
    }

    suf[suflen]=n+1;
    for(int i=x;i>=1;i--){
        if(R[i]==0){
            suf[suflen-1]=suf[suflen]; --suflen;
        } else {
            if (R[i]<suf[suflen]) {
                suf[suflen-1]=L[i]; --suflen;
            } else {
                break;
            }
        }
    }
   
    LL ans=0;
    for(int i=x+1;i>=max(suflen,2);i--) {
        // use [i,x]
        int lef=0,rig=min(i-2,prelen)+1;
        while(rig-lef>1){
            int mid=(lef+rig)>>1;
            if(pre[mid]<suf[i]){
                lef=mid;
            } else {
                rig=mid;
            }
        }
        ans=ans+(lef+1);
    }
    cout<<ans<<endl;
}

 

前缀后缀——cf1167E

原文:https://www.cnblogs.com/zsben991126/p/10875303.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!