• SPOJ 7258 (后缀自动机)


    转载:http://hzwer.com/4492.html

    给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个。

    搞出后缀自动机

    dp处理出每个点往下走能够走出多少个串。
    f[i]=sigma(f[ch[i][c])+1
    这个可以按Max排序之后倒着推就好了。
    询问的时候看一下走下去个数是否<=k,是的话就走下去,然后–k;否则就找下一条边

      1 1
      2 2
      3 3
      4 4
      5 5
      6 6
      7 7
      8 8
      9 9
     10 10
     11 11
     12 12
     13 13
     14 14
     15 15
     16 16
     17 17
     18 18
     19 19
     20 20
     21 21
     22 22
     23 23
     24 24
     25 25
     26 26
     27 27
     28 28
     29 29
     30 30
     31 31
     32 32
     33 33
     34 34
     35 35
     36 36
     37 37
     38 38
     39 39
     40 40
     41 41
     42 42
     43 43
     44 44
     45 45
     46 46
     47 47
     48 48
     49 49
     50 50
     51 51
     52 52
     53 53
     54 54
     55 55
     56 56
     57 57
     58 58
     59 59
     60 60
     61 61
     62 62
     63 63
     64 64
     65 65
     66 66
     67 67
     68 68
     69 69
     70 70
     71 71
     72 72
     73 73
     74 74
     75 75
     76 76
     77 77
     78 78
     79 79
     80 #include<iostream>
     81 #include<cstdio>
     82 #include<cstring>
     83 #include<cstdlib>
     84 #include<algorithm>
     85 #include<cmath>
     86 #define N 180005
     87 #define inf 1000000000
     88 using namespace std;
     89 char ch[N];
     90 int Q,p,q,np,nq;
     91 int cnt=1,last=1,n;
     92 int fa[N],to[N][26],l[N],s[N];
     93 int f[N],v[N];
     94 void extend(int c)
     95 {
     96     p=last;np=last=++cnt;l[np]=++n;
     97     for(;p&&!to[p][c];p=fa[p])to[p][c]=np;
     98     if(!p)fa[np]=1;
     99     else 
    100     {
    101         int q=to[p][c];
    102         if(l[p]+1==l[q])fa[np]=q;
    103         else 
    104         {
    105             nq=++cnt;l[nq]=l[p]+1;
    106             memcpy(to[nq],to[q],sizeof(to[q]));
    107             fa[nq]=fa[q];
    108             fa[q]=fa[np]=nq;
    109             for(;to[p][c]==q;p=fa[p])to[p][c]=nq;
    110         }
    111     }
    112 }
    113 void build()
    114 {
    115     scanf("%s",ch);
    116     for(char *c=ch;*c;c++)extend(*c-'a');    
    117 }
    118 void pre()
    119 {
    120     for(int i=1;i<=cnt;i++)v[l[i]]++;
    121     for(int i=1;i<=n;i++)v[i]+=v[i-1];
    122     for(int i=1;i<=cnt;i++)s[v[l[i]]--]=i;
    123     for(int i=cnt;i;i--)
    124     {
    125         f[s[i]]=1;
    126         for(int j=0;j<26;j++)
    127             f[s[i]]+=f[to[s[i]][j]];
    128     }
    129 }
    130 void query()
    131 {
    132     p=1;int x;
    133     scanf("%d",&x);
    134     while(x)
    135     {
    136         for(int i=0;i<26;i++)
    137             if(to[p][i])
    138             {
    139                 if(f[to[p][i]]>=x)
    140                 {
    141                     putchar('a'+i);
    142                     p=to[p][i];
    143                     --x;break;
    144                 }
    145                 else x-=f[to[p][i]];
    146             }
    147     }
    148     printf("
    ");
    149 }
    150 int main()
    151 {
    152     build();
    153     pre();
    154     scanf("%d",&Q);
    155     while(Q--)
    156         query();
    157     return 0;
    158 }
  • 相关阅读:
    用python3实现AES/CBC/PKCS5padding算法加解密
    python之逆向某贷款app破解sign参数
    用Python实现RSA签名和验签
    python3 RSA 长字符串分段加密解密
    PyCharm 字体大小颜色常用功能设置
    pycharm2019.3/pycharm2020.2 专业版 安装教程永久激活
    Android 四大组件和Intent
    Linux的查找命令
    Linux(centos)系统各个目录的作用详解
    linux ls文件颜色和底色设置
  • 原文地址:https://www.cnblogs.com/agenthtb/p/7696201.html
Copyright © 2020-2023  润新知