zoukankan      html  css  js  c++  java
  • SPOJ

    SPOJ - SUBLEX

    思路:求第k大字串,求出sam上每个节点开始能识别多少字串,然后从起点开始跑就好啦。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PII pair<int, int>
    #define PLI pair<LL, int>
    #define PDD pair<double,double>
    #define ull unsigned long long
    using namespace std;
    
    const int N = 90000 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, ans[N];
    LL dp[N << 1];
    char s[N];
    
    struct SuffixAutomaton {
        int last, cur, cnt, ch[N<<1][26], id[N<<1], fa[N<<1], dis[N<<1], sz[N<<1], c[N];
        SuffixAutomaton() {cur = cnt = 1;}
        void init() {
            for(int i = 1; i <= cnt; i++) {
                memset(ch[i], 0, sizeof(ch[i]));
                sz[i] = c[i] = dis[i] = fa[i] = 0;
            }
            cur = cnt = 1;
        }
        void extend(int c, int id) {
            last = cur; cur = ++cnt;
            int p = last; dis[cur] = id;
            for(; p && !ch[p][c]; p = fa[p]) ch[p][c] = cur;
            if(!p) fa[cur] = 1;
            else {
                int q = ch[p][c];
                if(dis[q] == dis[p]+1) fa[cur] = q;
                else {
                    int nt = ++cnt; dis[nt] = dis[p]+1;
                    memcpy(ch[nt], ch[q], sizeof(ch[q]));
                    fa[nt] = fa[q]; fa[q] = fa[cur] = nt;
                    for(; ch[p][c]==q; p=fa[p]) ch[p][c] = nt;
                }
            }
            sz[cur] = 1;
        }
        void getSize(int n) {
            for(int i = 1; i <= cnt; i++) c[dis[i]]++;
            for(int i = 1; i <= n; i++) c[i] += c[i-1];
            for(int i = cnt; i >= 1; i--) id[c[dis[i]]--] = i;
            for(int i = cnt; i >= 1; i--) {
                int p = id[i];
                sz[fa[p]] += sz[p];
            }
        }
        void work(int u, int k) {
            if(!k) return;
            LL ret = 0;
            for(int i = 0; i < 26; i++) {
                if(!ch[u][i]) continue;
                if(ret + dp[ch[u][i]] + 1 >= k) {
                    putchar(i + 'a');
                    work(ch[u][i], k - ret - 1);
                    break;
                }
                ret += dp[ch[u][i]] + 1;
            }
        }
        void solve() {
            for(int i = cnt; i >= 1; i--) {
                int u = id[i]; dp[u] = 0;
                for(int c = 0; c < 26; c++)
                    if(ch[u][c]) dp[u] += dp[ch[u][c]] + 1;
            }
            int q, k; scanf("%d", &q);
            while(q--) {
                scanf("%d", &k);
                work(1, k);
                puts("");
            }
        }
    } sam;
    
    
    int main() {
        scanf("%s", s + 1);
        n = strlen(s + 1);
        for(int i = 1; i <= n; i++)
            sam.extend(s[i]-'a', i), ans[i] = 0;
        sam.getSize(n);
        sam.solve();
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    负载均衡的基础技术种类
    scp基本使用方法
    给linux添加yum源。
    Linux 克隆虚拟机引起的“Device eth0 does not seem to be present, delaying initialization”
    FastDFS-单机版安装
    已安装nginx动态添加模块
    FastDFS
    七、CentOS 6.5 下 Nginx的反向代理和负载均衡的实现
    www.xxx.com 与 m.xxx.com 的Nginx服务器实现
    六、CentOS 6.5 下Nginx的配置
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9818153.html
Copyright © 2011-2022 走看看