---
tags: VNOJ, Free Contest, Implementation, String, SPyofgame
---
Free Contest Testing Round 20 - SEG
=====
[https://oj.vnoi.info/problem/fct020_seg](https://oj.vnoi.info/problem/fct020_seg)
-----
Contributer: [mr_sg](https://codeforces.com/profile/giangcbg)
-----
###### tags: `Implementation`, `String`
-----
### Xét bài toán con
Xét một dãy $X =$ "**<<<...<<<>>>...>>>**"
Gọi $L$ là số lần xuất hiện "**<**"
Gọi $R$ là số lần xuất hiện "**>**"
Thì dãy nguyên không âm có tổng nhỏ nhất tạo được là
$0 < 1 < 2 < \dots < L - 1 < max(L, R) > R - 1 > \dots > 2 > 1 > 0$
Với tổng của dãy này là
$V(X) = (0 + 1 + 2 + \dots + L - 1) + max(L, R) + (R - 1 + \dots + 2 + 1 + 0) = \frac{L(L-1)}{2} + max(L, R) + \frac{R(R-1)}{2}$
------
### Trở về bài toán chính
Vậy với một xâu $S$ bất kì, ta phải tách về các xâu con để tính
Để thuận tiện cho việc tính toán và tránh phải xử lí cho trường hợp không có "**<**" hay "**>**". Ta sẽ nén mảng thành một tập $A$ chứa các cặp "**{char, int}**" biểu thị có **int** số lượng kí tự **char** (**char** là **<** hoặc **>**).
Vậy nếu bên trái $S$ không có **<** có thể chèn vào đầu $A$ {"**<**", $0$}
Và nếu bên phải $S$ không có **>** có thể chèn vào cuối $A$ {"**>**", $0$}
Khi này chỉ cần tính kết quả giữa các cặp "**<>**" kề nhau
------
### Code
> **Time:** $O(|s|)$
> **Space:** $O(|s|)$
> **Algo:** Implementation, String
>
```cpp=
#include <iostream>
#include <vector>
using namespace std;
/// 0 + 1 + 2 + ... + n - 1
long long natural_sum(int n)
{
return 1LL * n * (n - 1) / 2;
}
int main()
{
/// Input
string s;
cin >> s;
/// String compression
vector<pair<char, int> > T;
T.reserve(s.size());
if (s.front() != '<') T.push_back(make_pair('<', 0));
for (char c : s)
{
if (T.empty() || T.back().first != c)
T.push_back(make_pair(c, 1));
else
T.back().second++;
}
if (s.back() != '>') T.push_back(make_pair('>', 0));
/// Calculating
long long res = 0;
for (int i = 1; i < T.size(); i += 2)
{
/// Peak of sequence 0 < 1 < ... < T[i-1]-1 < peak > T[i-0]-1 > ... > 1 > 0
int peak = max(T[i - 1].second, T[i - 0].second);
res += natural_sum(T[i - 1].second); /// Sum of Left sequence (not include peak) 0 < 1 < ... < T[i-1] - 1 < [peak]
res += natural_sum(T[i - 0].second); /// Sum of Right sequence (not include peak) [peak] > T[i-0] - 1 > ... > 1 > 0
res += peak;
}
/// Output
cout << res;
return 0;
}
```