概述
题目:就是给你一个串,对于第i个位置,你可以把前i个字符放到队尾形成一个新的字符串,问你最后一共有几个字符串
DC3卡过去了hhhh
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
using namespace std;
const int maxn=2000001;
int wa[maxn*3],wb[maxn*3],wv[maxn*3],wss[maxn*3];
int c0(int *r,int a,int b)
{
return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];
}
int c12(int k,int *r,int a,int b)
{
if(k==2)
return r[a]<r[b]||(r[a]==r[b]&&c12(1,r,a+1,b+1));
else return r[a]<r[b]||(r[a]==r[b]&&wv[a+1]<wv[b+1]);
}
void sort(int *r,int *a,int *b,int n,int m)
{
int i;
for(i=0;i<n;i++) wv[i]=r[a[i]];
for(i=0;i<m;i++) wss[i]=0;
for(i=0;i<n;i++) wss[wv[i]]++;
for(i=1;i<m;i++)wss[i]+=wss[i-1];
for(int i=n-1;i>=0;i--)
b[--wss[wv[i]]]=a[i];
}
void dc3(int *r,int *sa,int n,int m)
{
int i,j,*rn=r+n;
int *san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
r[n]=r[n+1]=0;
for(i=0;i<n;i++) if(i%3!=0)wa[tbc++]=i;
sort(r+2,wa,wb,tbc,m);
sort(r+1,wb,wa,tbc,m);
sort(r,wa,wb,tbc,m);
for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++)
rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++;
if(p<tbc)dc3(rn,san,tbc,p);
else for(i=0;i<tbc;i++) san[rn[i]]=i;
for(i=0;i<tbc;i++) if(san[i]<tb)wb[ta++]=san[i]*3;
if(n%3==1)wb[ta++]=n-1;
sort(r,wb,wa,ta,m);
for(i=0;i<tbc;i++)wv[wb[i]=G(san[i])]=i;
for(i=0,j=0,p=0;i<ta&&j<tbc;p++)
sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++];
for(;i<ta;p++)sa[p]=wa[i++];
for(;j<tbc;p++)sa[p]=wb[j++];
}
void da(int str[],int sa[],int ra[],int height[],int n,int m)
{
for(int i=n;i<3*n;i++)
str[i]=0;
dc3(str,sa,n+1,m);
int i,j,k=0;
for(int i=0;i<=n;i++) ra[sa[i]]=i;
for(int i=0;i<n;i++)
{
if(k) k--;
int j=sa[ra[i]-1];
while(str[i+k]==str[j+k])k++;
height[ra[i]]=k;
}
}
int m,n,k,t;
int ra[maxn*3],height[maxn*3],str[maxn*3],sa[maxn*3];
char s[maxn];
int book[maxn]={0};
#include<vector>
vector<int>ans[maxn];
int main()
{
scanf("%s",s);
n=strlen(s);
m=n;
for(int i=0;i<n;i++)
str[i]=s[i]-'a'+1;
for(int i=n;i<n*2;i++)
str[i]=str[i-n];
n*=2;
str[n]=0;
da(str,sa,ra,height,n,30);
int num=0;
for(int i=0;i<m;i++)
if(!book[i])
{
ans[++num].push_back(i);
int k=ra[i];
while(k-1>=1&&sa[k-1]<=m&&height[k]>=m)
{
k--;
if(sa[k]==m) continue;
book[sa[k]]=1;
ans[num].push_back(sa[k]);
}
k=ra[i];
while(k+1<n&&sa[k+1]<=m&&height[k+1]>=m)
{
k--;
if(sa[k]==m) continue;
book[sa[k]]=1;
ans[num].push_back(sa[k]);
}
}
printf("%dn",num);
for(int i=1;i<=num;i++)
{
printf("%d",ans[i].size());
sort(ans[i].begin(),ans[i].end());
for(int j=0;j<ans[i].size();j++)
printf(" %d",ans[i][j]);
puts("");
}
return 0;
}
kmp的算法
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int net[maxn],flag;
void kmp_pre(char x[],int m)
{
int i,j;
j=net[0]=-1;
i=0;
while(i<m)
{
while(j>-1&&x[i]!=x[j])
j=net[j];
net[++i]=++j;
}
if(m%(m-net[m])==0&&net[m]>0)//找寻环节
flag=m-net[m];
}
int n;
char s[maxn];
int main()
{
scanf("%s",s);
n=strlen(s);
flag=0;
kmp_pre(s,n);
if(flag)
{
printf("%dn",flag);
int num=n/flag;
for(int i=0;i<flag;i++)
{
printf("%d",num);
for(int j=i;j<n;j+=flag)
printf(" %d",j);
puts("");
}
}
else //否则都不是同一组
{
printf("%dn",n);
for(int i=0;i<n;i++)
printf("1 %dn",i);
}
return 0;
}
比赛时过题的hash哈希
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn=2e6+10;
ll p[maxn],ha[maxn];
const ll bas=31;
char s[maxn];
int n;
ll findha(int l,int r)
{
return ha[r]-ha[l-1]*p[r-l+1];
}
struct node{
int id;
ll w;
}ma[maxn];
struct node1{
int fi;
vector<int>a;
}ans[maxn];
bool cmp(const node &a,const node &b)
{
if(a.w==b.w) return a.id<b.id;
return a.w<b.w;
}
bool cp(const node1 &a,const node1 &b)
{
return a.fi<b.fi;
}
int main()
{
scanf("%s",s);
n=strlen(s);
for(int i=n;i<n+n;i++)
s[i]=s[i-n];
n*=2;
p[0]=1;
for(int i=1;i<=n;i++)
{
p[i]=p[i-1]*bas;
ha[i]=(ha[i-1]*bas+s[i-1]-'a'+1);
}
int m=n/2;
for(int i=1;i<=m;i++)
{
ll tmp=findha(i,i+m-1);
ma[i].id=i-1;
ma[i].w=tmp;
}
sort(ma+1,ma+m+1,cmp);
int num=0;
for(int i=1;i<=m;i++)
{
if(ma[i].w!=ma[i-1].w)
{
num++;
ans[num].fi=ma[i].id;
}
else ans[num].a.push_back(ma[i].id);
}
sort(ans+1,ans+num+1,cp);
printf("%dn",num);
for(int i=1;i<=num;i++)
{
printf("%d",ans[i].a.size()+1);
printf(" %d",ans[i].fi);
for(int j=0;j<ans[i].a.size();j++)
printf(" %d",ans[i].a[j]);
puts("");
}
return 0;
}
最后
以上就是平淡板凳为你收集整理的牛客网多校3 Sort String(后缀数组DC3)的全部内容,希望文章能够帮你解决牛客网多校3 Sort String(后缀数组DC3)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复