Hướng dẫn giải của Cuốn sách lạ


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Làm ngược lại, với mỗi kí tự, đếm xem nó là kí tự xuất hiện duy nhất trong bao nhiêu xâu con liên tiếp. Để một kí tự ~x~ ở vị trí ~i~ xuất hiện duy nhất trong xâu con thì nó không thể chứa kí tự ~x~ gần nhất về bên trái là ~j~ và bên phải ~k~. Số lượng xâu con có thể là ~(i - j) * (k - i)~. Tính giá trị này với từng vị trí.

Code:

#include <bits/stdc++.h>
using namespace std;

#define oo 2e18
#define mod 1000000007
#define inf32 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define get(x, i) (((x) >> (i)) & 1)
#define pi pair<int, int>
#define all(x) x.begin(), x.end()
#define Log2(x) 63 - __builtin_clzll(x)
#define set0(d) memset(d, 0, sizeof d)
#define setneg(d) memset(d, -1, sizeof d)
#define setinf(d) memset(d, inf32, sizeof d)
#define Unique(v) v.erase(unique(all(v)), v.end())
#define FILENAME "f"
#define int long long

const int maxn = 1e5 + 5;

vector<int> pos[26];
string s;

void solve(){
    cin >> s; s = '?' + s;
    int ans = 0;
    for(int i = 0; i < 26; i++) pos[i].clear(), pos[i].push_back(0);

    for(int i = 1; i < s.size(); i++){
        pos[s[i] - 'a'].push_back(i);
    }

    for(int i = 0; i < 26; i++){
        pos[i].push_back(s.size());
        for(int j =1; j <  pos[i].size() - 1; j++){
            ans += (pos[i][j + 1] - pos[i][j]) * (pos[i][j] - pos[i][j - 1]);
        }
    }
    cout << ans << '\n';
}

signed main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

    solve();
}