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. 2 months 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

  2. 1 month ago
    2026-9-25 14:07:28

    [9866]Betawin88: Login Daftar Slot Gacor Dana 5k dan Casino Live,Betawin88 menyediakan akses login dan daftar mudah untuk main slot gacor dana 5k serta judi casino live deposit pulsa. Ayo gabung dan coba keberuntunganmu! visit: betawin88

Send Comment Edit Comment


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