首页 > 编程知识 正文

next数组怎么求,线程状态是5种还是6种

时间:2023-05-05 23:02:04 阅读:173125 作者:4345

后缀数组算法思路:乘数基数排序

数组: sa (第I个小后缀的下标),rk (第I个小后缀)。

时间复杂性: o(nLOGN ) o ) nlogn ) o ) nlogn ) )。

JSOI2007字符加密(排序循环移动位置) ) ) ) ) ) )。

题意:给出字符串abcde。 他有多个循环移动位置。 是abcde、bcdea、cdeab、…、ebacd。 把这些重新排列一下。 按从小到大的顺序输出每个字符串的最后一个字符。

思路:将字符串复制到abcdeabcde后,计算后缀数组。

# include bits/stdc.husingnamespacestd; const int N=2e5 5; char s[N]; int n,sa[N],rk[N],oldrk[N1],id[N],px[N],cnt[N]; BOOLCMP(intx,int y,int w ) returnoldrk [ x ]==oldrk [ y ] oldrk [ xw ]==oldrk [ yw ]; (}int main ) ) { int i,m=200,p,w; scanf('%s ',s 1 ); n=Strlen(s1; for(I=1; i=n; I ) s(In )=s ) I ); n*=2; 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(w=1; w=1,m=p ) {for(p=0,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(Oldrk,rk,sizeof ) rk ); for(p=0,i=1; i=n; I ) rk[sa[I]=CMP(sa[I]、sa[i-1]、w )? p: p; if(p==n ) for ) intI=1; i=n; I ) sa(rk ) I )=I; 黑; }for(I=1; i=n; I () if ) sa[I]n/2 ) continue; printf('%c ',s[sa[i] n/2 - 1] ); (Putchar ) 10; } [USACO06DEC]Milk Patterns (出现次数大于k的长子列) ) ) )。

想法:

子串是后缀的前缀。

因此,我们将先对后缀进行排序。 排序后相邻的k个后缀的最长共同前缀的长度是答案。 k个后缀的最长公共前缀的长度是k-1个连续的height阵列。 用单调的队列保护答案。

# include bits/stdc.husingnamespacestd; const int N=2e4 5; int s[N]; int n,ht[N],sa[N],rk[N],oldrk[N1],id[N],px[N],cnt[1000002]; BOOLCMP(intx,int y,int w ) returnoldrk [ x ]==oldrk [ y ] oldrk [ xw ]==oldrk [ yw ]; (}int main ) ) { int i,m=1000000,p,w,k; scanf('%d%d ),n,k ); k----; for(I=1; i=n; I ) scanf('%d ',s[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(w=1; w=1,m=p ) {for(p=0,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(Oldrk,rk,sizeof ) rk ); for(p=0,i=1; i=n; I ) rk[sa[I]=CMP(sa[I]、sa[i-1]、w )? p: p; if(p==n ) for ) intI=1; i=n; I ) sa(rk ) I )=I; 黑; }for(I=1,p=0; i=n; I ) if(p )--p; while(s[Ip]==s[sa[rk[I]-1]p] ) p; ht[rk[i]]=p; (//单调队列维持长度为k的区间的height最小值的最大值) /时,维持递增的数列int ans=0; dequeint q; for(I=1; i=n; I ) while(q.size ) ) q.front )=i-k ) q.pop_front ); while(q.size ) ht [ q.back ]=ht [ I ] ) q.pop_back; q.push_back(I; if(I=k ) ans=max ) ans,ht[q.front; }printf('%dn”,ans ); }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。