kyopro_library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub dyktr06/kyopro_library

:heavy_check_mark: Count Substrings
(lib/dp/substring.hpp)

Count Substrings

概要

配列における、連続するとは限らない部分列の種類数を数え上げます。

使い方

計算量

配列の要素数を $N$ とする。

Verified with

Code

#pragma once

/**
 * @brief Count Substrings
 * @docs docs/dp/substring.md
 */

long long substrings(const string &s, const long long &m){
    int n = (int) s.size();

    vector<vector<int>> next(n + 1, vector<int>(26, n));
    for(int i = n - 1; i >= 0; i--){
        next[i] = next[i + 1];
        next[i][s[i] - 'a'] = i;
    }

    vector<long long> dp(n + 1, 0);
    dp[0] = 1;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < 26; ++j){
            if(next[i][j] >= n) continue;
            dp[next[i][j] + 1] += dp[i];
            dp[next[i][j] + 1] %= m;
        }
    }

    long long res = 0;
    for(int i = 0; i <= n; ++i){
        res += dp[i]; res %= m;
    }
    return res;
}

template <typename T>
long long subsequences(const vector<T> &s, const long long &m){
    int n = (int) s.size();
    map<T, int> mp;
    vector<long long> dp(n + 1);
    dp[0] = 1;
    for(int i = 0; i < n; i++){
        if(mp.count(s[i]) != 0){
            dp[i + 1] = dp[i] * 2 + m - dp[mp[s[i]]];
        } else{
            dp[i + 1] = dp[i] * 2;
        }
        dp[i + 1] %= m;
        mp[s[i]] = i;
    }
    return dp[n];
}
#line 2 "lib/dp/substring.hpp"

/**
 * @brief Count Substrings
 * @docs docs/dp/substring.md
 */

long long substrings(const string &s, const long long &m){
    int n = (int) s.size();

    vector<vector<int>> next(n + 1, vector<int>(26, n));
    for(int i = n - 1; i >= 0; i--){
        next[i] = next[i + 1];
        next[i][s[i] - 'a'] = i;
    }

    vector<long long> dp(n + 1, 0);
    dp[0] = 1;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < 26; ++j){
            if(next[i][j] >= n) continue;
            dp[next[i][j] + 1] += dp[i];
            dp[next[i][j] + 1] %= m;
        }
    }

    long long res = 0;
    for(int i = 0; i <= n; ++i){
        res += dp[i]; res %= m;
    }
    return res;
}

template <typename T>
long long subsequences(const vector<T> &s, const long long &m){
    int n = (int) s.size();
    map<T, int> mp;
    vector<long long> dp(n + 1);
    dp[0] = 1;
    for(int i = 0; i < n; i++){
        if(mp.count(s[i]) != 0){
            dp[i + 1] = dp[i] * 2 + m - dp[mp[s[i]]];
        } else{
            dp[i + 1] = dp[i] * 2;
        }
        dp[i + 1] %= m;
        mp[s[i]] = i;
    }
    return dp[n];
}
Back to top page