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

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #define maxn 1000005
     7 #define maxm 500005
     8 using namespace std;
     9 
    10 typedef long long ll;
    11 ll temp[26],sum[maxn];
    12 int n,t,k,tot,root,last,tmp[maxn],dist[maxn],fa[maxn],son[maxn][26],ri[maxn];
    13 bool bo=0;
    14 char st[maxm];
    15 struct Tsegment{
    16     void prepare(){tot=root=last=1;}
    17     int newnode(int x){dist[++tot]=x; return tot;}
    18     void add(int x){
    19         int p=last,np=newnode(dist[last]+1); last=np;
    20         for (;p&&!son[p][x];p=fa[p]) son[p][x]=np;
    21         if (p==0) fa[np]=root;
    22         else{
    23             int q=son[p][x];
    24             if (dist[p]+1==dist[q]) fa[np]=q;
    25             else{
    26                 int nq=newnode(dist[p]+1);
    27                 memcpy(son[nq],son[q],sizeof(son[q]));
    28                 fa[nq]=fa[q],fa[q]=fa[np]=nq;
    29                 for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
    30             }
    31         }
    32     }
    33     void dfs(int x,int rank){
    34         if (rank<=0){
    35             bo=1;
    36             return;
    37         }
    38         memset(temp,0,sizeof(temp));
    39         for (int i=0;i<26;i++){
    40             if (i==0) temp[i]=sum[son[x][i]];
    41             else temp[i]=temp[i-1]+sum[son[x][i]];
    42         }
    43         for (int i=0;i<26;i++){
    44             if (!son[x][i]) continue;
    45             if (temp[i]>=rank){
    46                 printf("%c",i+'a');
    47                 if (i==0){
    48                     if (t==0) dfs(son[x][i],rank-1);
    49                     else dfs(son[x][i],rank-ri[son[x][i]]);
    50                     if (bo==1) return;
    51                 }else{
    52                     if (t==0) dfs(son[x][i],rank-1-temp[i-1]);
    53                     else dfs(son[x][i],rank-ri[son[x][i]]-temp[i-1]);
    54                     if (bo==1) return;
    55                 }
    56             }
    57         }
    58     }
    59 }SAM;
    60 
    61 int main(){
    62     scanf("%s",st),n=strlen(st);
    63     SAM.prepare();
    64     for (int i=0;i<n;i++) SAM.add(st[i]-'a');
    65     memset(sum,0,sizeof(sum));
    66     for (int i=1;i<=tot;i++) sum[dist[i]]++;
    67     for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
    68     for (int i=1;i<=tot;i++) tmp[sum[dist[i]]--]=i;
    69     scanf("%d%d",&t,&k);
    70     last=root;
    71     memset(ri,0,sizeof(ri));
    72     for (int i=0;i<n;i++){
    73         int x=st[i]-'a';
    74         last=son[last][x],ri[last]=1;
    75     }
    76     for (int i=tot;i>=1;i--){
    77         int x=tmp[i];
    78         if (fa[x]) ri[fa[x]]+=ri[x];
    79     }
    80     ri[root]=0;
    81     memset(sum,0,sizeof(sum));
    82     for (int i=tot;i>=1;i--){
    83         int x=tmp[i];
    84         if (t==0) sum[x]=1;
    85         else sum[x]=ri[x];
    86         for (int j=0;j<26;j++){
    87             if (son[x][j]) sum[x]+=sum[son[x][j]];
    88         }
    89     }
    90     sum[root]=bo=sum[0]=0;
    91     SAM.dfs(root,k);
    92     if (bo==0) printf("-1
    ");
    93     else printf("
    ");
    94     return 0;
    95 }
    View Code

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998

    题目大意:对于一个给定长度为N的字符串,求它的第K小子串是什么。

     第一行是一个仅由小写英文字母构成的字符串S。

    第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。
     

     做法:看到这题,正解是对这个字符串建立一个后缀自动机,对每个节点记录一个信息:往下面匹配能匹配多少个字符串(在计算是,若t=0,则初始为1,否则初始权值为该节点的right值),最后从root开始贪心即可。

    后缀自动机+贪心。

  • 相关阅读:
    BZOJ1930 [Shoi2003]pacman 吃豆豆
    hdu5322 Hope
    hdu5390 tree
    hdu4609 3-idiots
    hdu5354 Bipartite Graph
    hdu4918 Query on the subtree
    hdu5314 Happy King
    [题解] PowerOJ 1741 最长递增子序列问题 (最大流)
    [题解] PowerOJ 1740 圆桌问题 (最大流)
    [题解] PowerOJ 1739 魔术球问题 (最大流)
  • 原文地址:https://www.cnblogs.com/OYzx/p/5551877.html
Copyright © 2011-2022 走看看