萌新求调简单sam板子
查看原帖
萌新求调简单sam板子
1254235
Priestess_SLG楼主2025/6/29 18:18
// #pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1000010;
const int mod = 998244353;
char s[N];
namespace SAM
{
    struct Node
    {
        signed ne[26];
        int fa, len, siz;
        inline Node() { memset(ne, fa = len = siz = 0, sizeof ne); }
    } tree[N << 1];
    int idx = 1, la = 1;
    int buc[N << 1];
    void ins(char ch)
    {
        int u = ++idx, p = la;
        tree[u].len = tree[la].len + 1;
        while (p && !tree[p].ne[ch - 'a'])
            tree[p].ne[ch - 'a'] = u, p = tree[p].fa;
        if (!p)
            tree[u].fa = 1;
        else
        {
            int q = tree[p].ne[ch - 'a'];
            if (tree[q].len == tree[p].len + 1)
                tree[u].fa = q;
            else
            {
                int nw = ++idx;
                tree[nw] = tree[q];
                tree[nw].len = tree[p].len + 1;
                tree[q].fa = tree[u].fa = nw;
                while (p && tree[p].ne[ch - 'a'] == q)
                    tree[p].ne[ch - 'a'] = nw, p = tree[p].fa;
            }
        }
        ++buc[u];
        la = u;
    }
} using namespace SAM;

int n, t, k, deg[N << 1], f[N << 1], g[N << 1], tmp[N << 1];
vector<int> adj[N << 1];

namespace sub1
{
    void print(int u, int cnt)
    {
        if (cnt < g[u])
            return;
        cnt -= g[u];
        for (int i = 0; i < 26; ++i)
            if (tree[u].ne[i])
            {
                if (f[tree[u].ne[i]] && cnt <= f[tree[u].ne[i]])
                {
                    cout << (char)(i + 'a');
                    print(tree[u].ne[i], cnt);
                    return;
                }
                cnt -= f[tree[u].ne[i]];
            }
        if (u == 1)
            cout << "-1\n";
    }
    void solve()
    {
        for (int i = idx; i; --i)
            for (int j = 0; j < 26; ++j)
                if (tree[i].ne[j])
                {
                    adj[tree[i].ne[j]].emplace_back(i);
                    ++deg[i];
                }
        queue<int> q;
        for (int i = 1; i <= idx; ++i)
        {
            tmp[i] = deg[i];
            if (!deg[i])
                q.emplace(i), g[i] = buc[i];
        }
        while (q.size())
        {
            int t = q.front();
            q.pop();
            for (int &v : adj[t])
            {
                g[v] += g[t];
                if (!--deg[v])
                    q.emplace(v);
            }
        }
        for (int i = 1; i <= idx; ++i)
            deg[i] = tmp[i];
        for (int i = 1; i <= idx; ++i)
            if (!deg[i])
                q.emplace(i);
        for (int i = 2; i <= idx; ++i)
            f[i] = g[i];
        while (q.size())
        {
            int t = q.front();
            q.pop();
            for (int &g : adj[t])
            {
                f[g] += f[t];
                if (!--deg[g])
                    q.emplace(g);
            }
        }
        // for (int i = 1; i <= idx; ++i)
        //     cout << f[i] << ' ';
        // cout << '\n';
        // f[1] -= g[1];
        g[1] = 0;
        if (f[1] < k && 0)
            cout << -1 << '\n';
        else
        {
            print(1, k - 1);
            cout << '\n';
        }
    }
}

namespace sub0
{
    void print(int u, int cnt)
    {
        if (!cnt)
            return;
        --cnt;
        for (int i = 0; i < 26; ++i)
            if (tree[u].ne[i])
            {
                if (cnt <= f[tree[u].ne[i]])
                {
                    cout << (char)(i + 'a');
                    print(tree[u].ne[i], cnt);
                    return;
                }
                cnt -= f[tree[u].ne[i]];
            }
    }
    void solve()
    {
        for (int i = idx; i; --i)
            for (int j = 0; j < 26; ++j)
                if (tree[i].ne[j])
                {
                    adj[tree[i].ne[j]].emplace_back(i);
                    ++deg[i];
                }
        queue<int> q;
        for (int i = 1; i <= idx; ++i)
            if (!deg[i])
                q.emplace(i);
        for (int i = 2; i <= idx; ++i)
            f[i] = 1;
        while (q.size())
        {
            int t = q.front();
            q.pop();
            for (int &g : adj[t])
            {
                f[g] += f[t];
                if (!--deg[g])
                    q.emplace(g);
            }
        }
        // for (int i = 1; i <= idx; ++i)
        //     cout << f[i] << ' ';
        // cout << '\n';
        if (f[1] < k)
            cout << -1 << '\n';
        else
        {
            print(1, k);
            cout << '\n';
        }
    }
}

signed main()
{
    // freopen("1.in", "r", stdin);
    // freopen("1.out", "w", stdout);
    scanf("%s", s + 1);
    n = strlen(s + 1), t, k;
    cin >> t >> k;
    for_each(s + 1, s + n + 1, [&](char &o) { ins(o); });
    t ? sub1::solve() : sub0::solve();
    return 0;
}

/*

abcadabcac
1 55

*/

wa 90pts,都是t=1,一个too long on line 2还有一个把有解判成无解了

2025/6/29 18:18
加载中...