• 【BZOJ3998】弦论 【后缀自动机】


    题意

      给定一个长度为n的字符串,求他的第k小子串是什么。

    分析

    T=0的时候,这个题跟SPOJ-SUBLEX的做法一样,当T=1的时候,不同位置的子串算多个,那么初始化的时候d[u]=cnt[u],没走一个字符不是k-1而是k-cnt[u]。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 const int maxn=1e6+5;
      8 char s[maxn];
      9 int n,T,k;
     10 
     11 struct state{
     12     int len,link;
     13     int next[26];
     14 }st[2*maxn];
     15 int last,cur,sz;
     16 int cnt[2*maxn],d[2*maxn],c[2*maxn];
     17 void init(){
     18     sz=1;
     19     last=cur=0;
     20     st[0].link=-1;
     21     st[0].len=0;
     22 //    memset(st[0].next,-1,sizeof(st[0].next));
     23 }
     24 
     25 void build_sam(int c){
     26     cur=sz++;
     27     st[cur].len=st[last].len+1;
     28     cnt[cur]=1;
     29 //    memset(st[cur].next,-1,sizeof(st[cur].next));
     30     int p;
     31     for(p=last;p!=-1&&st[p].next[c]==0;p=st[p].link){
     32         st[p].next[c]=cur;
     33     }
     34     if(p==-1)
     35         st[cur].link=0;
     36     else{
     37         int q=st[p].next[c];
     38         if(st[q].len==st[p].len+1)
     39             st[cur].link=q;
     40         else{
     41             int clone=sz++;
     42             st[clone].len=st[p].len+1;
     43             st[clone].link=st[q].link;
     44             for(int i=0;i<26;i++)
     45                 st[clone].next[i]=st[q].next[i];
     46             for(;p!=-1&&st[p].next[c]==q;p=st[p].link){
     47                 st[p].next[c]=clone;
     48             }
     49             st[q].link=st[cur].link=clone;
     50         }
     51     }
     52     last=cur;
     53 }
     54 int cmp(int a,int b){
     55     return st[a].len>st[b].len;
     56 }
     57 void solve(int k,int ty){
     58     if(d[0]<k){
     59         printf("-1
    ");
     60         return ;
     61     }
     62     int u=0;
     63     while(k){
     64         for(int i=0;i<26;i++){
     65             int v=st[u].next[i];
     66             if(v==0)continue;
     67             if(k>d[v])
     68                 k-=d[v];
     69             else{
     70                 printf("%c",i+'a');
     71                 u=v;
     72                 if(ty==0)
     73                     k--;
     74                 else
     75                     k-=cnt[v];
     76                 break;
     77             }
     78         }
     79     }
     80 }
     81 void update(){
     82     for(int i=1;i<sz;i++){
     83         int o=c[i];
     84         for(int j=0;j<26;j++){
     85             int v=st[o].next[j];
     86             if(v==0)continue;
     87             d[o]+=d[v];
     88         }
     89     }
     90     for(int i=0;i<26;i++){
     91         int v=st[0].next[i];
     92         if(v==0)continue;
     93             d[0]+=d[v];
     94     }
     95 }
     96 
     97 int main(){
     98     scanf("%s",s);
     99     n=strlen(s);
    100     init();
    101     for(int i=0;i<n;i++)
    102         build_sam(s[i]-'a');
    103     for(int i=0;i<sz;i++)
    104         c[i]=i;
    105     sort(c+1,c+sz,cmp);
    106     scanf("%d%d",&T,&k);
    107     if(T==0){
    108         for(int i=1;i<sz;i++)
    109             d[i]=1;
    110         update();
    111         solve(k,0);
    112     }else{
    113         for(int i=1;i<sz;i++){
    114             int o=c[i];
    115             if(st[o].link!=-1){
    116                 cnt[st[o].link]+=cnt[o];
    117             }
    118         }
    119         for(int i=1;i<sz;i++)
    120             d[i]=cnt[i];
    121         update();
    122         solve(k,1);
    123     }
    124 return 0;
    125 }
    View Code
  • 相关阅读:
    generator
    JS 中 apply 、call 、bind的详解
    前端面试题(24-js)
    JS原型链深入了解
    Java12新特性
    Java11-ZGC
    Java11新特性
    Java10新特性
    Java9新特性
    CF1385E【Directing Edges】 (拓扑排序)
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9888116.html
Copyright © 2020-2023  润新知