欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Educational Codeforces Round 65 (Rated for Div. 2) E. Range Deleting(双指针+思维)

程序员文章站 2023-12-25 18:01:03
...

题目链接
Educational Codeforces Round 65 (Rated for Div. 2) E. Range Deleting(双指针+思维)

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
const int maxn=1e6+50;
int n,x;///max{a[i]} <= x
int a[maxn];
int l[maxn];///l[i]:数字i第一次出现的位置
int r[maxn];///r[i]:数字i最后一次出现的位置
int L[maxn];///L[i]:数字[i,n]最先出现的位置
int R[maxn];///R[i]:数字[1,i]最后出现的位置
ll Solve()
{
    mem(l,INF);
    mem(r,0);
    for(int i=1;i <= n;++i)
    {
        l[a[i]]=min(i,l[a[i]]);
        r[a[i]]=i;
    }
    mem(L,INF);
    mem(R,0);
    for(int i=x;i >= 1;--i)
        L[i]=min(L[i+1],l[i]);
    for(int i=1;i <= x;++i)
        R[i]=max(R[i-1],r[i]);
    int k=x;///如果[k,x]非递减,那么k-1找下一个位置
    for(;k > 1 && r[k] <= L[k+1];--k);
    ll ans=x-k+1;
    ///要确保[1,i-1]非递减
    ///且已知[k+1,x]非递减
    for(int i=2;i <= x && R[i-2] <= l[i-1];++i)
    {
        for(;k < i || R[i-1] > L[k+1];++k);///找到第一个使得R[i-1]>=L[k+1]的k
        ans += x-k+1;
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&x);
    for(int i=1;i <= n;++i)
        scanf("%d",a+i);

    printf("%lld\n",Solve());
    return 0;
}

上一篇:

下一篇: