//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll n, a[N], l[N], r[N], p[N], ans;
inline ll read(){
ll x = 0, m = 1;
char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') m = -1;
ch = getchar();
}
while(isdigit(ch)){
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * m;
}
inline void write(ll x){
if(x < 0){
putchar('-');
write(-x);
return;
}
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
struct Code{
ll lst, len, sum;
bool operator <(const Code &x)const{
return len < x.len || (len == x.len && lst > x.lst);
}
};
priority_queue<Code> q;
signed main(){
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = read();
for(int i = 1; i <= n; ++ i) a[i] = read();
int now = a[1], lst = 1;
a[0] = -1314520, a[n + 1] = -1314521;
for(int i = 2; i <= n + 1; ++ i){
if(a[i] != now){
q.push(Code{lst, i - lst, now});
r[lst] = i - 1, l[i - 1] = lst;
p[lst] = i - lst;
now = a[i], lst = i;
}
}
while(!q.empty()){
Code u = q.top(); q.pop();
// cout << u.lst << ' ' << u.len << endl << endl;
// for(int i = 1; i <= n; ++ i) cout << l[i] << ' ' << r[i] << endl;cout << endl;
if(p[u.lst] != u.len) continue;
++ ans;
if(a[u.lst - 1] == a[u.lst + u.len]){
p[l[u.lst - 1]] += p[u.lst + u.len];
r[l[u.lst - 1]] = r[u.lst + u.len];
q.push(Code{l[u.lst - 1], r[u.lst + u.len] - l[u.lst - 1] + 1, a[u.lst - 1]});
}
}
write(ans);
return 0;
}
思路就是优先队列,用双向链表存每一个块的左右端点,pi 表示以 i 为左端点的当前块长,最后答案大了。