Problem:
Score : 300 points

Problem Statement

Given is a string S of length N-1.
Each character in S is < or >.

A sequence of N non-negative integers, a_1,a_2,\cdots,a_N, is said to be good when the following condition is satisfied for all i (1 \leq i \leq N-1):

If S_i= <: a_i<a_{i+1}

If S_i= >: a_i>a_{i+1}

Find the minimum possible sum of the elements of a good sequence of N non-negative integers.

Constraints

2 \leq N \leq 5 \times 10^5

S is a string of length N-1 consisting of < and >.

Input

Input is given from Standard Input in the following format:

S

Output

Find the minimum possible sum of the elements of a good sequence of N non-negative integers.

Sample Input 1

<>>

Sample Output 1

3

a=(0,2,1,0) is a good sequence whose sum is 3.
There is no good sequence whose sum is less than 3.

Sample Input 2

<>>><<><<<<<>>><

Sample Output 2

28

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::cmp;

fn main() {
    let s = std::io::stdin();
    let mut sc = Scanner { stdin: s.lock() };
    let s = sc.chars();
    let n = s.len() + 1;

    let mut x = vec![];
    for i in 1..(n - 1) {
        let left = s[i - 1];
        let right = s[i];
        if left == '<' && right == '>' {
            x.push(i);
        }
    }

    if s[0] == '>' {
        x.push(0);
    }
    if s[n - 2] == '<' {
        x.push(n - 1);
    }

    let mut ans = vec![0; n];
    for x in x.into_iter() {
        if x == 0 {
            let mut right = x;
            while right + 1 < n - 1 && s[right + 1] == '>' {
                right += 1;
            }
            for i in x..(right + 2) {
                ans[i] = cmp::max(ans[i], right + 1 - i);
            }
        } else if x == n - 1 {
            let mut left = x - 1;
            while left > 0 && s[left - 1] == '<' {
                left -= 1;
            }
            for i in left..(x + 1) {
                ans[i] = cmp::max(i - left, ans[i]);
            }
        } else {
            let mut left = x - 1;
            while left > 0 && s[left - 1] == '<' {
                left -= 1;
            }
            let mut right = x;
            while right + 1 < n - 1 && s[right + 1] == '>' {
                right += 1;
            }
            for i in left..(x + 1) {
                ans[i] = cmp::max(i - left, ans[i]);
            }
            for i in x..(right + 2) {
                ans[i] = cmp::max(ans[i], right + 1 - i);
            }
        }
    }

    println!("{}", ans.iter().sum::<usize>());
}

/// < >>> << >0<<<<<5>>> <

pub struct Scanner<R> {
    stdin: R,
}

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n')
            .take_while(|&b| b != b' ' && b != b'\n')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}