SAM求调
查看原帖
SAM求调
823131
jwjl楼主2023/1/28 17:18
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int long long
const int N = 1000007;
class ingenious
{
public:
    ingenious();
};
struct SAM
{
    int son[26];
    int endpos;
    int len;
    int father;
    int siz;
}sam[N];int last;int top;
int bin[N];
int topu[N];
void newNode(int length){
    int now = ++top;
    sam[now].len = length;
    sam[now].father = 0;
    memset(sam[now].son,0,sizeof(sam[now].son));    
}
void init(){
    last = 1;
    top = 0;
    newNode(0);
}
int k;
void Insert(int c){
    newNode(sam[last].len + 1);
    int p = last;
    int cur = top;
    sam[cur].endpos = 1;
    while (p != -1 && sam[p].son[c] == 0)
    {
        sam[p].son[c] = cur;
        p = sam[p].father;
    }
    if (p == -1){
        sam[cur].father = 0;
    }
    else{
        int q = sam[p].son[c];
        if (sam[p].len + 1 == sam[q].len){
            sam[cur].father = q;
        }
        else{
            newNode(sam[p].len + 1);
            int nq = top;
            memcmp(sam[nq].son,sam[q].son,sizeof(sam[q].son));
            sam[nq].father = sam[q].father;
            sam[cur].father = sam[q].father = nq;
            while (p >= 0 && sam[p].son[c] == q){
                sam[p].son[c] = nq;
                p = sam[p].father;
            }
        }
    }
    last = cur;
}
void Sort(){
    for (int i = 1;i <= top;i++)bin[sam[i].len]++;
    for (int i = 1;i <= top;i++)bin[i] += bin[i - 1];
    for (int i = 1;i <= top;i++)topu[bin[sam[i].len]--] = i;
}
void dp(int op){
    if (op == 0){
        for (int i = 1;i <= top;i++){
            sam[i].endpos = 1;
        }
    }
    else{
        for (int i = top;i >= 1;i--){
            if (sam[topu[i]].father == -1)continue;
            sam[sam[topu[i]].father].endpos += sam[topu[i]].endpos;
        }
    }
}
int dfs(int d){
    if (sam[d].siz)return sam[d].siz;
    sam[d].siz = sam[d].endpos;
    for (int i = 0;i < 26;i++){
        if (sam[d].son[i]){
            sam[d].siz += dfs(sam[d].son[i]);
        }
    }
    return sam[d].siz;
}
ingenious::ingenious(){
    string S;
    cin >>  S;
    init();
    for (int i = 0;i < S.length();i++){
        int c = S[i] - 'a';
        Insert(c);
    }
    int op;cin >> op >> k;
    Sort();
    dp(op);
    int sum = 0;
    for (int i = 1;i <= top;i++)sum += sam[i].endpos * (sam[i].len - sam[sam[i].father].len);
    if (sum < k){
        cout << -1 << '\n';
    }
    else{
        dfs(0);
        int now = 0;
        while (1)
        {
            //cout << k << endl;
            if (k <= 0)break;
            //else k -= sam[now].endpos;
            for (int i = 0;i < 26;i++){
                if (sam[now].son[i]){
                    if(k <= sam[sam[now].son[i]].siz){
                        k -= sam[sam[now].son[i]].endpos;
                        now = sam[now].son[i];
                        putchar(i + 'a');
                        break;
                    }
                    else k -= sam[sam[now].son[i]].siz;
                }
            }
        }
        
    }
    
    //for (int i = 0;i < 26;i++)cout << sam[0].son[i] << " ";
    /*for (int i = 1;i <= top;i++)cout << topu[i] << " ";cout << '\n';
    for (int i = 1;i <= top;i++)cout << sam[i].father << " ";cout << '\n';*/
    /*for (int i = 0;i <= top;i++)cout << sam[i].endpos << " ";cout << '\n';
    for (int i = 0;i <= top;i++)cout << sam[i].siz << " ";*/
    //for (int i = 0;i < Ia;i++)cout << ans[i];cout << '\n';
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    ingenious almighty;
    return 0;
}
2023/1/28 17:18
加载中...