結果

問題 No.2162 Copy and Paste 2
コンテスト
ユーザー vjudge1
提出日時 2026-10-08 21:10:02
言語 C++23
(gcc 15.3.0 + boost 1.92.0 + ACL)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 61 ms / 7,000 ms
+ 689µs
コード長 2,603 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,265 ms
コンパイル使用メモリ 175,728 KB
実行使用メモリ 11,508 KB
最終ジャッジ日時 2026-10-08 21:10:23
合計ジャッジ時間 4,587 ms
ジャッジサーバーID
(参考情報)
judge3_0 / judge4_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 26
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <algorithm>
#include <iostream>
#include <numeric>
#include <string>
#include <utility>
#include <vector>

using namespace std;
using u64 = unsigned long long;

constexpr int B1 = 1919, B2 = 1145, M1 = 998244853, M2 = 1e9 + 1111, N = 2e5;

inline int add(int x, int y, int mod) { return x + y >= mod ? x + y - mod : (x + y < 0 ? x + y + mod : x + y); }
inline int mul(int x, int y, int mod) { return x * (u64)y % mod; }

struct DSU {
    vector<int> fa;

    DSU(int n)
        : fa(n)
    {
        iota(fa.begin(), fa.end(), 0);
    }

    int root(int u) { return fa[u] == u ? u : fa[u] = root(fa[u]); }

    void merge(int from, int to)
    {
        from = root(from);
        to = root(to);
        if (from != to)
            fa[from] = to;
    }
};

int base1[N + 1], base2[N + 1];

void prepare()
{
    base1[0] = base2[0] = 1;
    for (int i = 1; i <= N; ++i) {
        base1[i] = mul(base1[i - 1], B1, M1);
        base2[i] = mul(base2[i - 1], B2, M2);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    prepare();

    string S;
    cin >> S;

    int n = S.size();
    vector<int> hsh1(n + 1), hsh2(n + 1);

    S = ' ' + S;
    for (int i = 1; i <= n; ++i) {
        hsh1[i] = add(hsh1[i - 1], mul(S[i], base1[i], M1), M1);
        hsh2[i] = add(hsh2[i - 1], mul(S[i], base2[i], M2), M2);
    }

    auto get_hsh = [&](int l, int r) -> pair<int, int> { return { mul(add(hsh1[r], -hsh1[l - 1], M1), base1[N - r], M1), mul(add(hsh2[r], -hsh2[l - 1], M2), base2[N - r], M2) }; };

    vector<int> lcp(n + 1); // lcp[i] := the LCP of S and S[i, n]
    for (int i = 1; i <= n; ++i) {
        int l = 1, r = n - i + 1;
        while (l < r) {
            int mid = (l + r + 1) >> 1;
            if (get_hsh(1, mid) == get_hsh(i, i + mid - 1))
                l = mid;
            else
                r = mid - 1;
        }

        if (get_hsh(1, l) == get_hsh(i, i + l - 1))
            lcp[i] = l;
    }

    DSU valid(n + 1);
    for (int i = 1; i < n; ++i) {
        if (lcp[i + 1] == 0)
            valid.merge(i, i + 1);
    }

    vector<int> g(n + 1);
    for (int j = 1; j <= n; ++j) {
        g[j] = max(g[j], g[j - 1]);

        int f = g[j] - 1, i = j;
        while (true) {
            i = valid.root(i);
            if (i + j > n)
                break;
            if (lcp[i + 1] < j) {
                valid.merge(i, i + 1);
                continue;
            }

            f += j - 1;
            g[i + j] = max(g[i + j], f);
            i += j;
        }
    }

    cout << n - g[n] << '\n';
    return 0;
}
0