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
复制代码

 

posted @   朝暮不思  阅读(153)  评论(0编辑  收藏  举报
编辑推荐:
· Brainfly: 用 C# 类型系统构建 Brainfuck 编译器
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
阅读排行:
· Tinyfox 发生重大改版
· DeepSeek 全面指南,95% 的人都不知道的9个技巧(建议收藏)
· 对比使用DeepSeek与文新一言,了解DeepSeek的关键技术论文
· Brainfly: 用 C# 类型系统构建 Brainfuck 编译器
· DeepSeekV3+Roo Code,智能编码好助手
点击右上角即可分享
微信分享提示