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

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

    讲道理是一道很水的后缀自动机的题目,后缀自动机+第K大而已。

    但像我这种蒟蒻,膜拜hzwer学长的博客膜了好久才改出来。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define inf 1<<30
     5 #define maxn 500005
     6 using namespace std;
     7 int t,k,n;
     8 char s[maxn];
     9 struct sam{
    10     int last,tot,par[maxn*2],val[maxn*2],sum[maxn*2],size[maxn*2],v[maxn],q[maxn*2],go[maxn*2][26];
    11     sam(){last=++tot;}
    12     int newnode(int x){val[++tot]=val[x]+1;return tot;}
    13     void extend(int x){
    14         int p=last,np=newnode(p); size[np]=1;
    15         while(p&&go[p][x]==0) go[p][x]=np,p=par[p];
    16         if(p==0) par[np]=1;
    17         else{
    18             int q=go[p][x];
    19             if(val[q]==val[p]+1) par[np]=q;
    20             else{
    21                 int nq=newnode(p);
    22                 memcpy(go[nq],go[q],sizeof(go[q]));
    23                 par[nq]=par[q]; par[q]=par[np]=nq;
    24                 while(p&&go[p][x]==q) go[p][x]=nq,p=par[p];
    25             }
    26         }
    27         last=np;
    28     }
    29     void calc(){
    30         for(int i=1;i<=tot;i++) v[val[i]]++;
    31         for(int i=1;i<=n;i++) v[i]+=v[i-1];
    32         for(int i=tot;i;i--) q[v[val[i]]--]=i;
    33         for(int i=tot;i;i--){
    34             if(t==1) size[par[q[i]]]+=size[q[i]];
    35             else size[q[i]]=1;
    36         }
    37         size[1]=0;
    38         for(int i=tot;i;i--){
    39             sum[q[i]]=size[q[i]];
    40             for(int j=0;j<26;j++) sum[q[i]]+=sum[go[q[i]][j]];
    41         }
    42     }
    43     void dfs(int x,int y){
    44         if(y<=size[x]) return;
    45         y-=size[x];
    46         for(int i=0;i<26;i++){
    47             if(go[x][i]==0) continue;
    48             if(y<=sum[go[x][i]]){
    49                 putchar(i+'a'); dfs(go[x][i],y); return;
    50             }
    51             y-=sum[go[x][i]];
    52         }
    53     }
    54 }sam;
    55 int main(){
    56     scanf("%s",s+1); n=strlen(s+1);
    57     scanf("%d%d",&t,&k);
    58     for(int i=1;i<=n;i++) sam.extend(s[i]-'a');
    59     sam.calc();
    60     if(k>sam.sum[1]) puts("-1");
    61     else sam.dfs(1,k);
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    单例模式
    二、CSS
    十一、多线程
    十二、协程
    十、多进程
    九、内存管理
    八、元类
    七、上下文管理器/魔术方法
    六、单例模式
    五、装饰器
  • 原文地址:https://www.cnblogs.com/longshengblog/p/5551152.html
Copyright © 2011-2022 走看看