zoukankan      html  css  js  c++  java
  • 【uoj35】 后缀排序

    http://uoj.ac/problem/35 (题目链接)

    题意

      如题,并且求height数组。

    Solution

      挂一发后缀自动机构后缀数组及height数组

    细节

      注意基数排序和连边的时候不要把根节点也算进去

    代码

    // uoj35
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=100010;
    int sa[maxn],height[maxn];
    char s[maxn];
    
    namespace SAM {
    	int par[maxn<<1],len[maxn<<1],r[maxn<<1],ch[maxn<<1][26],pos[maxn<<1];
    	int last,sz,Dargen,n,cnt;
    	int b[maxn],id[maxn<<1],head[maxn<<1];
    	
    	struct edge {int to,next;}e[maxn<<2];
    	
    	void link(int u,int v) {
    		e[++cnt]=(edge){v,head[u]};head[u]=cnt;
    	}
    	void Extend(int c) {
    		int np=++sz,p=last;last=np;
    		pos[np]=len[np]=r[np]=len[p]+1;
    		for (;p && !ch[p][c];p=par[p]) ch[p][c]=np;
    		if (!p) par[np]=Dargen;
    		else {
    			int q=ch[p][c];
    			if (len[p]+1==len[q]) par[np]=q;
    			else {
    				int nq=++sz;
    				len[nq]=len[p]+1;r[nq]=r[q];
    				memcpy(ch[nq],ch[q],sizeof(ch[q]));
    				par[nq]=par[q];
    				par[np]=par[q]=nq;
    				for (;p && ch[p][c]==q;p=par[p]) ch[p][c]=nq;
    			}
    		}
    	}
    	void build() {
    		last=sz=Dargen=1;
    		n=strlen(s+1);
    		for (int i=1;i<=n>>1;i++) swap(s[i],s[n-i+1]);
    		for (int i=1;i<=n;i++) Extend(s[i]-'a');
    	}
    	void dfs(int x,int l) {
    		if (pos[x]) sa[++sz]=n-pos[x]+1,height[sz]=l;
    		for (int i=head[x];i;i=e[i].next) {
    			if (i==head[x]) dfs(e[i].to,pos[x] ? len[x] : l);
    			else dfs(e[i].to,len[x]);
    		}
    	}
    	void pre() {
    		for (int i=1;i<=sz;i++) b[s[r[i]-len[par[i]]]-'a']++;
    		for (int i=1;i<=26;i++) b[i]+=b[i-1];
    		for (int i=2;i<=sz;i++) id[b[s[r[i]-len[par[i]]]-'a']--]=i;
    		for (int i=sz-1;i>=1;i--) link(par[id[i]],id[i]);
    		sz=0;dfs(1,0);
    	}
    }
    using namespace SAM;
    	
    int main() {
    	scanf("%s",s+1);
    	build();
    	pre();
    	for (int i=1;i<=n;i++) printf("%d ",sa[i]);
    	puts("");
    	for (int i=2;i<=n;i++) printf("%d ",height[i]);
    	return 0;
    }
    
  • 相关阅读:
    react系列教程
    实现 React Hooks
    实现 call、apply、bind
    Webpack概念
    写一个简单的模板引擎
    闭包和let块级作用域
    react系列(六)Redux Saga
    react系列(五)在React中使用Redux
    java学习12天2020/7/17
    java学习第十一天2020/7/16
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6307256.html
Copyright © 2011-2022 走看看