codeforces 899e Segments Removal

来源:互联网 发布:bind源码 内网dns 编辑:程序博客网 时间:2024/05/24 02:36

Segments Removal

Vasya has an array of integers of length n.

Vasya performs the following operations on the array: on each step he finds the longest segment of consecutive equal integers (the leftmost, if there are several such segments) and removes it. For example, if Vasya’s array is [13, 13, 7, 7, 7, 2, 2, 2], then after one operation it becomes [13, 13, 2, 2, 2].

Compute the number of operations Vasya should make until the array becomes empty, i.e. Vasya removes all elements from it.

Input

The first line contains a single integer n (1 ≤ n ≤ 200 000) — the length of the array.

The second line contains a sequence a1, a2, …, an (1 ≤ ai ≤ 109) — Vasya’s array.

Output

Print the number of operations Vasya should make to remove all elements from the array.

Examples

input

42 5 5 2

output

2

input

56 3 4 1 5

output

5

input

84 4 4 2 2 100 100 100

output

3

input

610 10 50 10 50 50

output

4

题面不难,给你一个序列,每次把其中最左边连续相等的数字去除,问最多需要多少次可以将整个序列全部除去。开始一直都是用set存每个线段的起点,终点和长度,但是每次在删除和合并的时候不知道如何处理线段的长度问题。看了题解之后,才发现,我们可以有两种方式储存线段,一是起点加终点,二是起点加长度。在这道题中,我们在删除一个线段后,就不是很容易算出合并之后的线段长度,用起点加长度就可以避免这个问题。
代码如下:

#include<bits/stdc++.h>using namespace std;const int maxn = 2e5 + 6;int n;int a[maxn];set<pair<int, int> >s1, s2;int main(){    ios::sync_with_stdio(false);    cin >> n;    int l, r;    for(l = 1, r = 1; r <= n; r++) {        cin >> a[r];        if(a[r] != a[l]) {            s1.insert({l - r, l});            s2.insert({l, r - l});            l = r;        }    }    s1.insert({l - r, l});    s2.insert({l, r - l});    int cnt = 0;    while(s1.size() > 1) {        cnt++;        pair<int, int> temp = *s1.begin();        s1.erase(temp);        int st = temp.second;        int len = -temp.first;        auto lpos = s2.lower_bound({st, len});        auto rpos = s2.upper_bound({st, len});        if(lpos == s2.begin() || rpos == s2.end()) {            s2.erase({st, len});            continue;        }        lpos--;        if(a[lpos->first] == a[rpos->first]) {            int st1 = lpos->first, st2 = rpos->first;            int len1 = lpos->second, len2 = rpos->second;            s1.erase({ -len1, st1});            s1.erase({ -len2, st2});            s2.erase({st1, len1}), s2.erase({st2, len2});            s1.insert({ -len1 - len2, st1});            s2.insert({st1, len1 + len2});        }        s2.erase({st, len});    }    cnt++;    cout << cnt << endl;    return 0;}
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 山麂是几级保护动物 麂怎么读 麂皮 麂皮鞋怎么清洗 麂皮绒 麂皮绒面料怎么清洗 麂皮绒面料 黑麂 麂皮绒面料优缺点 赤麂 aj灰麂皮 麂肉 aj麂皮 aj1灰麂皮 麂皮绒怎么清洗 麂皮绒清洗 麂皮清洗 格子麂皮绒 提花麂皮绒 斜纹麂皮绒 麂皮绒风衣 麂皮绒是真皮吗 麂皮绒衣服怎么清洗 麂皮绒复合面料 麂皮绒印花 麂皮绒夹克 四面弹麂皮绒 双面麂皮绒 yeezy500麂皮鞋头怎么清洗 山麓 山麓的拼音 山麓的意思 城市山麓 山麓是什么意思 山麓迪安萨城市学院 沈阳金地半山麓 大明靖远侯 风雪燕山麓 山老鼠 山鼠 穿山鼠