zoukankan      html  css  js  c++  java
  • 弦论[TJOI2015]

    我们建SAM,在SAM上跑DP:(SAM不会点这里

       当T=1时,cnt.fa+=cnt;(因为这时我们一个点代表了很多的子串。)

       当T=0时,cnt=1

       然后DFS出解。

    #include<bits/stdc++.h>
    #define N 1000005
    using namespace std;
    struct po{int len,ch[26],fa;}s[N];
    int nq,last=1,cnt[N],sum[N],p,np,tot=1,k,T,len,id[N],c[N];
    char ch[N];
    inline void Sam(int x){
        nq=++tot; s[nq].len=s[last].len+1;
        for (;last&&!s[last].ch[x];last=s[last].fa) s[last].ch[x]=nq;
        if (!last) s[nq].fa=1; else {
            p=s[last].ch[x];
            if (s[last].len+1==s[p].len) s[nq].fa=p; else {
                np=++tot; s[np]=s[p];
                s[np].len=s[last].len+1;
                s[p].fa=s[nq].fa=np;
                for (;last&&s[last].ch[x]==p;last=s[last].fa) s[last].ch[x]=np;
            }
        } last=nq; cnt[last]=1;
    }
    void dfs(int x){
        k-=cnt[x];
        if (k<=0) return;
        for (int i=0;i<26;i++)
         if (int t=s[x].ch[i]) {
             if (k<=sum[t]) {putchar('a'+i);dfs(t);return;}
             k-=sum[t];
         }
    }
    int main () {
        freopen("a.in","r",stdin);
        scanf("%s",ch+1); len=strlen(ch+1);
        for (int i=1;i<=len;i++) 
         Sam(ch[i]-'a');
        for (int i=1;i<=tot;i++) c[s[i].len]++;
        for (int i=1;i<=len;i++) c[i]+=c[i-1];
        for (int i=1;i<=tot;i++) id[c[s[i].len]--]=i;
        scanf("%d%d",&T,&k);
        for (int i=tot;i;i--) T?cnt[s[id[i]].fa]+=cnt[id[i]]:cnt[id[i]]=1; 
        cnt[1]=0;
        for (int i=tot;i;i--) {
            sum[id[i]]=cnt[id[i]];
            for (int j=0;j<26;j++) sum[id[i]]+=sum[s[id[i]].ch[j]];
        }
        if (sum[1]<k)  {puts("-1");return 0;}
        dfs(1); 
        return 0;
    }
  • 相关阅读:
    OC内存管理
    摘要算法
    加密算法
    编码技术
    Golang遇到的一些问题总结
    SignalR
    uni-app 小程序 vue
    C# 调用 C++ dll的两种方式
    Vue 项目 VSCode 调试
    Navicat 导出 表结构
  • 原文地址:https://www.cnblogs.com/rrsb/p/8325252.html
Copyright © 2011-2022 走看看