zoukankan      html  css  js  c++  java
  • [洛谷P1368]工艺

    题意

    给定一个环,从任意一个点出发形成一个串,求这个串的最小字典序

    思路

    O(n)做法最小表示法不会,再见

    按照处理环的套路,先倍长了再说


    后缀数组SA

    显然就是求最小的后缀,但是要注意这个后缀长度必须不小于n,后缀排序裸题(因为数据过水所以不需要离散化)


    后缀自动机SAM

    据说这道题被卡了但还是提一下

    对倍长后的串建SAM之后,从root向下走最小的边走n次即可

    Code;

    #include<bits/stdc++.h>
    #define N 600005
    using namespace std;
    int n,m,len,a[N],sa[N],rk[N],tp[N],h[N],cnt[N];
    
    template <class T>
    void read(T &x)
    {
    	char c;int sign=1;
    	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    	while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
    }
    void radix_sort()
    {
    	for(int i=0;i<=m;++i) cnt[i]=0;
    	for(int i=1;i<=len;++i) cnt[rk[i]]++;
    	for(int i=1;i<=m;++i) cnt[i]+=cnt[i-1];
    	for(int i=len;i>=1;--i) sa[cnt[rk[tp[i]]]--]=tp[i];
    }
    void get_sa()
    {
    	m=200;
    	for(int i=1;i<=len;++i) rk[i]=a[i],tp[i]=i;
    	radix_sort();
    	for(int t=1;t<len;t<<=1)
    	{
    		int p=0;
    		for(int i=1;i<=t;++i) tp[++p]=len-t+i;
    		for(int i=1;i<=len;++i) if(sa[i]>t) tp[++p]=sa[i]-t;
    		radix_sort();
    		swap(rk,tp);
    		rk[sa[1]]=p=1;
    		for(int i=2;i<=len;++i) rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+t]==tp[sa[i-1]+t]) ? p : ++p;
    		if(p==len) break;
    		m=p;
    	}
    }
    void get_h()//可以不要qwq
    {
    	int ht=0;
    	for(int i=1;i<=len;++i) rk[sa[i]]=i;
    	for(int i=1;i<=len;++i)
    	{
    		int p=sa[rk[i]-1];
    		while(a[i+ht]==a[p+ht]) ++ht;
    		h[rk[i]]=ht;
    		ht=max(0,ht-1);
    	}
    }
    int main()
    {
    	read(n);len=n*2;
    	for(int i=1;i<=n;++i) read(a[i]),a[i+n]=a[i];
    	get_sa();
    	get_h();
    	int con=0,ans=len+1;
    	for(int i=1;i<=len;++i)
    	{
    		if(con&&h[i]<n) break;
    		if(sa[i]<=n) {con=1;ans=min(ans,sa[i]);}
    	}//相同的串取更前面那个,不过这道题并没有什么用。。。。。。
    	for(int i=ans;i<ans+n;++i) printf("%d ",a[i]);
    	return 0;
    }
    
  • 相关阅读:
    Leetcode 349. Intersection of Two Arrays
    hdu 1016 Prime Ring Problem
    map 树木品种
    油田合并
    函数学习
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 101. Symmetric Tree
    poj 2524 Ubiquitous Religions(宗教信仰)
    pat 1009. 说反话 (20)
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11326080.html
Copyright © 2011-2022 走看看