• bzoj3998 [TJOI2015]弦论(SAM)


    【题目链接】

      http://www.lydsy.com/JudgeOnline/problem.php?id=3998

    【题意】

      询问排名第k的子串是谁,0代表相同子串不同位置算作相同,1代表相同子串不同位置算作不同。  

    【思路】

      0的情况和这个题一样每个子串不同位置出现次数算作1;

      至于1,统计val作为该子串在不同位置出现的次数,就是求一下|right|的大小呗,相应修改一下就可以了。

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 const int N = 5*1e5+10;
     6 
     7 char s[N];
     8 int root,last,sz,ch[N][26],fa[N],sum[N],val[N],l[N];
     9 void add(int x) {
    10     int c=s[x]-'a';
    11     int p=last,np=++sz; last=np;
    12     l[np]=x+1; val[np]=1;
    13     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    14     if(!p) fa[np]=root;
    15     else {
    16         int q=ch[p][c];
    17         if(l[p]+1==l[q]) fa[np]=q;
    18         else {
    19             int nq=++sz; l[nq]=l[p]+1;
    20             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    21             fa[nq]=fa[q];
    22             fa[np]=fa[q]=nq;
    23             for(;p&&q==ch[p][c];p=fa[p]) ch[p][c]=nq;
    24         }
    25     }
    26 }
    27 
    28 int n,T,b[N],cnt[N];
    29 
    30 void get_sum() {
    31     for(int i=1;i<=sz;i++) cnt[l[i]]++;
    32     for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
    33     for(int i=sz;i>=1;i--) b[cnt[l[i]]--]=i;
    34     for(int i=sz;i;i--)
    35         if(!T) val[b[i]]=1;
    36         else val[fa[b[i]]]+=val[b[i]];
    37     val[1]=0;
    38     for(int i=sz;i;i--) {
    39         int p=b[i]; sum[p]=val[p];
    40         for(int j=0;j<26;j++)
    41             sum[p]+=sum[ch[p][j]];
    42     }
    43 }
    44 
    45 int main() {
    46     scanf("%s",s);
    47     n=strlen(s);
    48     root=last=++sz;
    49     for(int i=0;i<n;i++) add(i);
    50     scanf("%d",&T);
    51     int x,p=root; scanf("%d",&x);
    52     get_sum();
    53     if(x>sum[1]) { puts("-1");return 0; }
    54     while(x>val[p]) {
    55         for(int c=0;c<26;c++)if(ch[p][c]) {
    56             if(sum[ch[p][c]]>=x) {
    57                 putchar('a'+c);
    58                 x-=val[p]; p=ch[p][c];
    59                 break;
    60             }
    61             else x-=sum[ch[p][c]];
    62         }
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    码云的安装和配置
    Python解释器安装教程和环境变量配置
    Python基础学习
    buuctf CheckIn
    各种小马收集
    buuctf Easysql 小记
    locust
    封装好的日志模块
    实用的测试网站
    列表操作
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5200675.html
Copyright © 2020-2023  润新知