• loj111 后缀排序(后缀数组模板)


    未优化

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e6+10;
    char s[N];
    int cnt[N],id[N],rk[N<<1],sa[N<<1];
    int od[N<<1];
    int main(){
        //ios::sync_with_stdio(false);
        scanf("%s",s+1);
        int n=strlen(s+1);
        int m=max(n,300);
        int i;
        for(i=1;i<=n;i++)
            cnt[rk[i]=s[i]]++;
        for(i=1;i<=m;i++)
            cnt[i]+=cnt[i-1];
        for(i=n;i>=1;i--)
            sa[cnt[rk[i]]--]=i;
        for(int w=1;w<n;w<<=1){
            memset(cnt,0,sizeof cnt);
            for(i=1;i<=n;i++) id[i]=sa[i];
            for(i=1;i<=n;i++) cnt[rk[id[i]+w]]++;
            for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
            for(i=n;i>=1;i--) sa[cnt[rk[id[i]+w]]--]=id[i];
            memset(cnt,0,sizeof cnt);
            for(i=1;i<=n;i++) id[i]=sa[i];
            for(i=1;i<=n;i++) cnt[rk[id[i]]]++;
            for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
            for(i=n;i>=1;i--) sa[cnt[rk[id[i]]]--]=id[i];
            memcpy(od,rk,sizeof rk);
            for(int p=0,i=1;i<=n;i++){
                if(od[sa[i]]==od[sa[i-1]]&&od[sa[i]+w]==od[sa[i-1]+w])
                    rk[sa[i]]=p;
                else
                    rk[sa[i]]=++p;
            }
    
        }
        for(i=1;i<=n;i++)
            printf("%d ",sa[i]);
    }
    View Code

    优化后

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e6+10;
    char s[N];
    int cnt[N],id[N],rk[N<<1],sa[N<<1];
    int od[N<<1],px[N];
    bool cmp(int x, int y, int w) {
      return od[x]==od[y]&&od[x+w]==od[y + w];
    }
    int main(){
        //ios::sync_with_stdio(false);
        scanf("%s",s+1);
        int n=strlen(s+1);
        int m=max(n,300);
        int i;
        for(i=1;i<=n;i++)
            cnt[rk[i]=s[i]]++;
        for(i=1;i<=m;i++)
            cnt[i]+=cnt[i-1];
        for(i=n;i>=1;i--)
            sa[cnt[rk[i]]--]=i;
        int p;
        for(int w=1;w<n;w<<=1,m=p){
            for(p=0,i=n;i>n-w;i--)
                id[++p]=i;
            for(i=1;i<=n;i++)
                if(sa[i]>w) id[++p]=sa[i]-w;
            memset(cnt,0,sizeof cnt);
            for(i=1;i<=n;i++) cnt[px[i]=rk[id[i]]]++;
            for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
            for(i=n;i>=1;i--) sa[cnt[px[i]]--]=id[i];
            memcpy(od,rk,sizeof rk);
            for(p=0,i=1;i<=n;i++){
                rk[sa[i]] = cmp(sa[i],sa[i - 1],w)?p:++p;
            }
        }
        for(i=1;i<=n;i++)
            printf("%d ",sa[i]);
    }
    View Code
  • 相关阅读:
    利用python做矩阵的简单运算(行列式、特征值、特征向量等的求解)
    numpy.linalg.svd函数
    梯度裁剪(Clipping Gradient):torch.nn.utils.clip_grad_norm
    tf.matmul()报错expected scalar type Float but found Double
    1283 最小周长
    1182 完美字符串
    1091 线段的重叠
    1090 3个数和为0
    1087 1 10 100 1000
    1083 矩阵取数问题
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13292393.html
Copyright © 2020-2023  润新知