「CF1167E」Range Deleting【双指针】

E. Range Deleting

time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output

You are given an array consisting of n n n integers a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an and an integer x x x. It is guaranteed that for every i i i, 1 ≤ a i ≤ x 1\leq a_i\leq x 1aix.

Let’s denote a function f ( l , r ) f(l,r) f(l,r) which erases all values such that l ≤ a i ≤ r l\leq a_i\leq r lair from the array a a a and returns the resulting array. For example, if a = [ 4 , 1 , 1 , 4 , 5 , 2 , 4 , 3 ] , a=[4,1,1,4,5,2,4,3], a=[4,1,1,4,5,2,4,3], then f ( 2 , 4 ) = [ 1 , 1 , 5 ] . f(2,4)=[1,1,5]. f(2,4)=[1,1,5].

Your task is to calculate the number of pairs ( l , r ) (l,r) (l,r) such that 1 ≤ l ≤ r ≤ x 1\leq l\leq r\leq x 1lrx and f ( l , r ) f(l,r) f(l,r) is sorted in non-descending order. Note that the empty array is also considered sorted.

Input

The first line contains two integers n n n and x x x ( 1 ≤ n , x ≤ 1 0 6 ) (1\leq n,x\leq 10^6) (1n,x106) — the length of array a a a and the upper limit for its elements, respectively.

The second line contains n n n integers a 1 , a 2 , … a n ( 1 ≤ a i ≤ x ) . a_1,a_2,…a_n (1\leq a_i \leq x). a1,a2,an(1aix).

Output

Print the number of pairs 1 ≤ l ≤ r ≤ x 1\leq l\leq r\leq x 1lrx such that f ( l , r ) f(l,r) f(l,r) is sorted in non-descending order.

Examples

input
3 3
2 3 1
output
4
input
7 4
1 3 1 2 2 4 3
output
6

Note

In the first test case correct pairs are ( 1 , 1 ) , ( 1 , 2 ) , ( 1 , 3 ) (1,1), (1,2), (1,3) (1,1),(1,2),(1,3) and ( 2 , 3 ) . (2,3). (2,3).

In the second test case correct pairs are ( 1 , 3 ) , ( 1 , 4 ) , ( 2 , 3 ) , ( 2 , 4 ) , ( 3 , 3 ) (1,3), (1,4), (2,3), (2,4), (3,3) (1,3),(1,4),(2,3),(2,4),(3,3) and ( 3 , 4 ) . (3,4). (3,4).

题意

  • 就是给你一个序列,然后你可选择两个数 l l l r r r使得 1 ≤ l ≤ r ≤ x 1\leq l\leq r \leq x 1lrx,使得删去序列中所有满足 l ≤ a i ≤ r l\leq a_i \leq r lair的数后序列非严格递减,问有多少对可行的 l   r l\ r l r,空序列满足条件

题解

  • 由于非递减序列的子序列荏苒非递减,所以对于删去一段区间 [ l , r ] [l,r] [l,r]的数后,所有大于 r r r的数的最小位置一定大于所有小于 l l l的数的最大位置,首先可以预处理出弱删除 [ 1 , i ] [1,i] [1,i]或者 [ i , x ] [i,x] [i,x]的所有数后剩下的所有数是否构成非递减序列,并且分别记录剩下的数的最左边位置和最右边位置,最后枚举左端点 l l l,用另外一个指针去找最小的 r r r满足以下几个条件

    1. r ≥ l r\geq l rl
    2. 删去 [ 1 , r ] [1,r] [1,r]的数剩下的数非递减
    3. 删去 [ 1 , r ] [1,r] [1,r]的数剩下的数中最左边数的位置 > > >删去 [ l , x ] [l,x] [l,x]后剩下的数中最右边的数的位置

    然后 a n s + = x − r + 1 ans+=x-r+1 ans+=xr+1即可

代码

#include<bits/stdc++.h>

using namespace std;
#define inf 0x3f3f3f3f
const int maxn=1e6+10;

int n,x,a[maxn],l[maxn],r[maxn];
vector<int> pos[maxn];
bool canl[maxn],canr[maxn];

int main()
{
    scanf("%d %d",&n,&x);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]].push_back(i);
    int p=inf;
    memset(canl,false,sizeof(canl));
    memset(canr,false,sizeof(canr));
    for(int i=x+1;i>=1;i--) {
        if(pos[i].empty()) {
            canl[i-1]=true;
            l[i-1]=p;
            continue;
        }
        if(pos[i].back()<=p) {
            canl[i-1]=true;
            l[i-1]=p=pos[i][0];
        }else break;
    }
    p=-1;
    for(int i=0;i<=x;i++) {
        if(pos[i].empty()) {
            canr[i+1]=true;
            r[i+1]=p;
            continue;
        }
        if(pos[i][0]>p) {
            canr[i+1]=true;
            r[i+1]=p=pos[i].back();
        }else break;
    }

    long long ans=0;int point=0;
    for(int i=1;i<=x&&canr[i];i++) {
        while(point<x&&(point<i||!canl[point]||l[point]<r[i])) point++;
        ans+=(x-point+1);
    }
    printf("%lld\n",ans);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值