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;}