CSES Substring Order II
// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define VI vector<int>
#define VII vector<vector<int>>
#define VIII vector<vector<vector<int>>>
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x), __VA_ARGS__})
#define cmax(x,...) x=max({(x), __VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define uint unsigned long long
#define MAXN 200010


struct sam {
    struct node {
        map<char, node*> next;
        node *link;
        int minlen, maxlen;
        int suf = 0;
        int endpos;
        int tot = 0, size = 0;
    };
    vector<node> datalist;
    int total = 0;
    node *last = nullptr, *root = nullptr;
    string s;

    node *newnode(int length = 0, node *p = nullptr) {
        node *x = &datalist[total++];
        x->minlen = 0;
        x->maxlen = length;
        x->link = p;
        return x;
    }
    sam(string str) {
        s = str;
        datalist.resize(s.size() * 2);
        root = last = newnode();
        root->endpos = 0;
        for (int i = 0; i < sz(s); ++i) {
            char c = s[i];
            node *cur = newnode(i+1, root);
            cur->endpos = i+1;
            cur->tot = 1;
            node *parent = last;
            while (parent && !parent->next.count(c)) {
                parent->next[c] = cur;
                parent = parent->link;
            }
            if (parent) {
                node *q = parent->next[c];
                if (parent->maxlen + 1 == q->maxlen) cur->link = q;
                else {
                    node *nq = newnode(parent->maxlen + 1, q->link);
                    nq->endpos = i+1;
                    nq->next = q->next;
                    q->link = cur->link = nq;
                    while (parent && parent->next[c] == q) {
                        parent->next[c] = nq;
                        parent = parent->link;
                    }
                }
            }
            last = cur;
        }
        // minlen
        queue<node*> q; q.push(root);
        while (!q.empty()) {
            node *x = q.front(); q.pop();
            for (auto [c, p]: x->next) {
                if (p->minlen) continue;
                p->minlen = x->minlen + 1;
                q.push(p);
            }
        }
        // is suffix
        for (node *x = last; x && x != root; x = x->link) x->suf = 1;
        // size of endpos set
        vector<vector<node*>> e(total);
        rep(i, 0, total) if (datalist[i].link) e[datalist[i].link - &datalist[0]].push_back(&datalist[i]);
        function<void(int)> dfs_tot = [&](int x) {
            for (auto y: e[x]) {
                dfs_tot(y - &datalist[0]);
                datalist[x].tot += datalist[y - &datalist[0]].tot;
            }
        };
        dfs_tot(0);
        // num of strings
        function<int(node*)> dfs_size = [&](node *x) {
            if (x->size) return x->size;
            x->size = x==root ? 0 : x->tot;
            for (auto [c, p]: x->next) x->size += dfs_size(p);
            return x->size;
        };
        dfs_size(root);
    }
    string getstr(node *x) {
        return s.substr(x->endpos - x->maxlen, x->maxlen);
    }
    void graphviz_dump(string filename = "graph.dot") {
        FILE *f = fopen(filename.c_str(), "w");
        fprintf(f, "digraph {\n");
        rep(i, 0, total) {
            node *x = &datalist[i];
            fprintf(f, "    %lld[%s shape=\"record\" label=\"", i, x->suf ? "color=\"red\"" : "");
            vector<string> desired = {
                "min=" + to_string(x->minlen),
                "max=" + to_string(x->maxlen),
                "endpos=" + to_string(x->tot),
                "sz=" + to_string(x->size)
            };
            rep(j, 0, sz(desired)) {
                fprintf(f, "%s%s", j ? " | " : "", desired[j].c_str());
            }
            fprintf(f, "\"];\n");
        }
        rep(i, 0, total) {
            for (auto [c, p]: datalist[i].next) {
                fprintf(f, "    %lld -> %ld ;\n", i, p - &datalist[0], c);
            }
        }
        // rep(i, 0, total) if (datalist[i].link) fprintf(f, "    %lld -> %ld [color=\"blue\" style=\"dashed\"];\n", i, datalist[i].link - &datalist[0]);
        fprintf(f, "}\n");
    }
    void solve(int k) {
        node *x = root;
        for (; ; ) {
            if (x != root && k <= x->tot) break;
            if (x != root) k -= x->tot;
            for (auto [c, p]: x->next) {
                if (k <= p->size) {
                    cout << c;
                    x = p;
                    break;
                }
                k -= p->size;
            }
        }
        cout << endl;
    }
};

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

    string s; cin >> s;
    int k; cin >> k;
    sam a(s);
    // a.graphviz_dump();
    a.solve(k);

    return 0;
}

Comments

  1. 3 weeks ago
    2026-8-27 14:14:58

    [4636]primogaming Official Login | Best Online Slots PH with GCash,Experience the thrill of PrimoGaming, the premier destination for online slots and casino games in the Philippines. Login or register today to download the app and claim your exclusive welcome bonus. Join now for secure betting and the best gaming rewards! visit: primogaming

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
Previous
Next