Educational Codeforces Round 65 (Rated for Div. 2)E. 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 nn integers a1,a2,…,ana1,a2,…,an and an integer xx. It is guaranteed that for every ii, 1≤ai≤x1≤ai≤x.

Let's denote a function f(l,r)f(l,r) which erases all values such that l≤ai≤rl≤ai≤r from the array aa 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], then 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) such that 1≤l≤r≤x1≤l≤r≤x and 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 nn and xx (1≤n,x≤1061≤n,x≤106) — the length of array aa and the upper limit for its elements, respectively.

The second line contains nn integers a1,a2,…ana1,a2,…an (1≤ai≤x1≤ai≤x).

Output

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

Examples

input

Copy

3 3
2 3 1

output

Copy

4

input

Copy

7 4
1 3 1 2 2 4 3

output

Copy

6

Note

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

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

 

 

分析:不降序列要求满足,a[i].w<a[j].w&&a[i].id<a[j].id,可以证明若一个单调不降的数组按照第一关键字w,第二关键字id进行排序,排序后id是上升的。

因为要求删除的是w连续的区间,所以直接对原数组重新排序,即问题变成了有多少个连续的区间使得删去这个区间后剩下的数组是单调的。类似于HihoCoder - 1797,不过一个是计数,一个是求最大值,大同小异,找左边最长连续,右边最长连续,然后二分一下计数即可。

#include "bits/stdc++.h"

using namespace std;

struct node {
    long long w, id;

    bool friend operator<(node a, node b) {
        if (a.w == b.w)return a.id < b.id;
        else return a.w < b.w;
    }
} a[1000004];

long long b[1000004][4];
long long l[1000004];
long long r[1000004];

int main() {
    long long n, x;
    cin >> n >> x;
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &a[i].w);
        a[i].id = i;
    }
    sort(a + 1, a + 1 + n);
    long long cnt = 1;
    b[cnt][0] = b[cnt][1] = a[1].id;
    b[cnt][3] = a[1].w;
    for (int i = 2; i <= n; ++i) {
        if (a[i].w == a[i - 1].w)b[cnt][1] = a[i].id;
        else {
            cnt++;
            b[cnt][0] = b[cnt][1] = a[i].id;
            b[cnt][3] = a[i].w;
        }
    }
    long long ans = 0;
    long long base = 0;
    long long lmax = 1;
    long long rmin = cnt;
    for (int i = 1; i <= cnt; ++i) {
        if (b[i][0] > base) {
            base = b[i][1];
            l[i] = base;
            lmax = i;
        } else break;
    }
    base = 1e9;
    for (int i = cnt; i >= 1; --i) {
        if (b[i][1] < base) {
            base = b[i][0];
            r[i] = base;
            rmin = i;
        } else break;
    }
    if (lmax < rmin) {
        for (int i = 1; i <= lmax; ++i) {
            int pos = upper_bound(r + (int) rmin, r + (int) cnt + 1, l[i]) - r;
            if (pos < cnt + 1)
                ans += (b[cnt][3] - b[pos - 1][3]) * (b[i + 1][3] - b[i][3]);
        }
        cout << ans + (b[lmax + 1][3] - b[1][3]) * (x - b[cnt][3] + 1) + (b[cnt][3] - b[rmin - 1][3]) * (b[1][3]) +
                (x - b[cnt][3] + 1) * (b[1][3]) << endl;
    } else {
        cout << x * (x + 1) / 2 << endl;
    }

}

 

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值