Problem:
Score : 600 points

Problem Statement

You are given a string s consisting of A, B and C.

Snuke wants to perform the following operation on s as many times as possible:

Choose a contiguous substring of s that reads ABC and replace it with BCA.

Find the maximum possible number of operations.

Constraints

1 \leq |s| \leq 200000

Each character of s is A, B and C.

Input

Input is given from Standard Input in the following format:

s

Output

Find the maximum possible number of operations.

Sample Input 1

ABCABC

Sample Output 1

3

You can perform the operations three times as follows: ABCABC → BCAABC → BCABCA → BCBCAA. This is the maximum result.

Sample Input 2

C

Sample Output 2

0

Sample Input 3

ABCACCBABCBCAABCB

Sample Output 3

6

Solution in Rust (1.15.1) (judge verdict: Time Limit Exceeded)

use std::cmp;
use std::collections::*;
use std::io::{self, Read};

fn main() {
    let stdin = io::stdin();
    let mut sc = Scanner::new(stdin.lock());

    let mut v: Vec<char>;
    {
        let s: String = sc.read().unwrap();
        v = s.chars().collect();
    };

    let l = v.len();
    if l < 3 {
        println!("{}", 0);
        return;
    }

    let mut ans = 0;
    loop {
        let mut f = false;
        let mut i = 0;
        while (i <= l - 3) {
            if v[i] == 'A' && v[i + 1] == 'B' && v[i + 2] == 'C' {
                v[i] = 'B';
                v[i + 1] = 'C';
                v[i + 2] = 'A';

                ans = ans + 1;
                f = true;
                i = i + 3;
            } else {
                i = i + 1;
            }
        }

        // println!("{:?}", v);

        if !f {
            break;
        }
    }

    println!("{}", ans);
}

struct Scanner<R: Read> {
    reader: R,
}

impl<R: Read> Scanner<R> {
    fn new(reader: R) -> Scanner<R> {
        Scanner { reader: reader }
    }

    fn read<T: std::str::FromStr>(&mut self) -> Option<T> {
        self.reader
            .by_ref()
            .bytes()
            .map(|b| b.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>()
            .parse()
            .ok()
    }

    fn read_vec<T: std::str::FromStr>(&mut self, n: usize) -> Option<Vec<T>> {
        (0..n).map(|_| self.read()).collect()
    }

    fn read_vec2d<T: std::str::FromStr>(&mut self, m: usize, n: usize) -> Option<Vec<Vec<T>>> {
        (0..m).map(|_| self.read_vec(n)).collect()
    }

    fn read_board(&mut self, n: usize) -> Option<Vec<Vec<char>>> {
        (0..n)
            .map(|_| {
                self.read::<String>()
                    .map(|s| s.chars().collect::<Vec<char>>())
            })
            .collect()
    }
}