zoukankan      html  css  js  c++  java
  • LG4051/BZOJ1031 「JSOI2007」字符加密 后缀数组

    问题描述

    BZOJ1031

    LG4051


    题解

    发现这是一个环,根据经验,破环为链,于是字符环变为了字符串

    之后对这个复制之后的字符串求后缀数组。

    $len$代表原字符串长度,代表复制后的字符串长度

    最后输出的时候,判断一下,如果$SA_i le len$,则输出$str_i$。


    Code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define maxn 1000007
     5 
     6 void read(int &x){
     7     x=0;char ch=1;int fh;
     8     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     9     if(ch=='-') fh=-1,ch=getchar();
    10     else fh=1;
    11     while(ch>='0'&&ch<='9'){
    12         x=(x<<1)+(x<<3)+ch-'0';
    13         ch=getchar();
    14     }
    15     x*=fh;
    16 }
    17 
    18 char s[maxn];
    19 int n,m,sa[maxn],x[maxn],y[maxn],ct[maxn];
    20 
    21 int chk(int x){
    22     return x>0?x:x+n;
    23 }
    24 
    25 void SA(){
    26     for(register int i=1;i<=n;i++) ct[x[i]=s[i]]++;
    27     for(register int i=2;i<=m;i++) ct[i]+=ct[i-1];
    28     for(register int i=n;i>=1;i--) sa[ct[x[i]]--]=i;
    29     for(register int k=1;k<=n;k<<=1){
    30         int tot=0;
    31         for(register int i=n-k+1;i<=n;i++) y[++tot]=i;
    32         for(register int i=1;i<=n;i++) if(sa[i]>k) y[++tot]=sa[i]-k;
    33         for(register int i=1;i<=m;i++) ct[i]=0;
    34         for(register int i=1;i<=n;i++) ct[x[i]]++;
    35         for(register int i=1;i<=m;i++) ct[i]+=ct[i-1];
    36         for(register int i=n;i>=1;i--) sa[ct[x[y[i]]]--]=y[i],y[i]=0;
    37         swap(x,y);x[sa[1]]=tot=1;
    38         for(register int i=2;i<=n;i++)
    39             if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]) x[sa[i]]=tot;
    40             else x[sa[i]]=++tot;
    41         if(tot==n) break;
    42         m=tot;
    43     }
    44 }
    45 
    46 int rnk[maxn];
    47 int let;
    48 int main(){
    49     ios::sync_with_stdio(0);
    50     cin>>(s+1);n=strlen(s+1);let=n;
    51     for(register int i=n+1;i<=n*2;i++) s[i]=s[i-n];
    52     n*=2;
    53     m=122;SA();
    54     for(register int i=1;i<=n;i++){
    55         rnk[sa[i]]=i;
    56     }
    57     for(register int i=1;i<=n;i++){
    58         if(sa[i]<=let)
    59             cout<<s[sa[i]+let-1];
    60     }
    61     cout<<endl;
    62     return 0;
    63 }
  • 相关阅读:
    Android开源库
    银行卡的数字检測
    hdu4941 Magical Forest
    android之检測是否有网络
    在Oracle数据库中使用NFS,怎样调优?
    centos+nginx+php-fpm+php include fastcgi_params php页面能訪问但空白,被fastcgi_params与fastcgi.conf害慘了
    漫谈反射
    Android 四大组件学习之BroadcastReceiver二
    【LeetCode】two num 利用comparable接口 对对象进行排序
    扩展功能==继承?
  • 原文地址:https://www.cnblogs.com/liubainian/p/11478736.html
Copyright © 2011-2022 走看看