学了后缀数组 做了后缀数组裸题23333
对于这题来说 只需要把长度为Len的字符串变成长度为2*Len的字符串 跑一遍后缀数组 然后就可以输出结果辣![快乐!]
上代码![板子打得丑QAQ]
- #include <bits/stdc++.h>
- using namespace std;
- char ss[1000005];
- int c[1000005],Rank[1000005],K,N,M,SA[1000005],Temp[1000005],a[1000005];
- void Build(int x)
- {
- for (int i=0;i<=x;i++)
- c[i]=0;
- for (int i=1;i<=N;i++)
- c[Rank[Temp[i]]]++;
- for (int i=1;i<=x;i++)
- c[i]+=c[i-1];
- for (int i=N;i>=1;i--)
- SA[c[Rank[Temp[i]]]--]=Temp[i];
- }
- void BuildSA()
- {
- for (int i=1;i<=N;i++)
- Rank[i]=a[i],Temp[i]=i;
- Build(M=300);
- for (int T=1;T<N;T*=2)
- {
- int p=0;
- for (int i=N-T+1;i<=N;i++)
- Temp[++p]=i;
- for (int i=1;i<=N;i++)
- if (SA[i]>T)
- Temp[++p]=SA[i]-T;
- Build(M=p);
- swap(Rank,Temp);
- Rank[SA[1]]=1;
- p=1;
- for (int i=2;i<=N;i++)
- {
- if (Temp[SA[i]]==Temp[SA[i-1]]&&Temp[SA[i]+T]==Temp[SA[i-1]+T]) Rank[SA[i]]=p;
- else Rank[SA[i]]=++p;
- }
- }
- }
- int main()
- {
- scanf("%s",ss+1);
- N=strlen(ss+1);
- for (int i=1;i<=N;i++)
- a[i]=ss[i],a[i+N]=a[i],ss[i+N]=ss[i]//把这个字符串复读一遍[误]
- N*=2;
- BuildSA();
- for (int i=1;i<=N;i++)
- if (SA[i]<=(N/2))
- cout<<ss[SA[i]+N/2-1];
- return 0;
- }