链接
https://codeforces.com/contest/1167/problem/E
题解
记录每种数字的最早和最晚出现位置
枚举左端点,然后用
p
o
i
n
t
e
r
pointer
pointer找一下右端点
代码
#include<bits/stdc++.h>
#define maxn 1000010
#define linf (1ll<<60)
#define iinf 0x3f3f3f3f
#define eps 1e-8
#define cl(x) memset(x,0,sizeof(x))
#define mod 998244353ll
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
int c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
ll N, x, tot,mn[maxn], mx[maxn], ans;
bool pre[maxn], suf[maxn];
int main()
{
ll p, t, i;
N=read(), x=read();
for(i=1;i<=x;i++)mn[i]=linf, mx[i]=-linf;
for(i=1;i<=N;i++)
{
t=read();
mn[t]=min(mn[t],i);
mx[t]=max(mx[t],i);
}
t=mx[1];
pre[1]=true;
for(i=2;i<=x;i++)
{
if(mn[i]==linf)pre[i]=true;
else
{
if(mn[i]>t)pre[i]=true, t=mx[i];
else break;
}
}
t=mn[x];
suf[x]=true;
for(i=x-1;i;i--)
{
if(mn[i]==linf)suf[i]=true;
else
{
if(mx[i]<t)suf[i]=true, t=mn[i];
else break;
}
}
mx[0]=-linf;
for(i=1;pre[i];i++)
if(mx[i]==-linf)mx[i]=mx[i-1];
mn[x+1]=linf;
for(i=x;suf[i];i--)
if(mn[i]==linf)mn[i]=mn[i+1];
p=i;
for(i=1;i<=x;i++)
{
if(i>1 and pre[i-1]==false)break;
if(p<i)p=i;
while(p<x and mn[p+1]<mx[i-1] )p++;
ans += x-p+1;
}
printf("%lld",ans);
return 0;
}