码迷,mamicode.com
首页 > 编程语言 > 详细

洛谷1368 工艺 - 后缀数组

时间:2018-02-15 18:27:46      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:pre   body   using   sort   for   gis   bsp   scan   ace   

题意:输入一个串,通过环形变换使它最小。(n<=300000)

裸的后缀排序啊!

(卡常把命都卡掉了)

后缀数组记得开大啊

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int x[1200005],y[1200005],u[1200005],v[1200005],r[1200005],o[1200005],n,m=700000;
 5 int str[600005],buf[600005];
 6 
 7 int main(){
 8     scanf("%d",&n);
 9     for(int i=1;i<=n;i++) scanf("%d",&str[i]),buf[i]=str[i];
10     sort(buf+1,buf+n+1);
11     for(int i=1;i<=n;i++) str[i]=lower_bound(buf+1,buf+n+1,str[i])-buf;
12     for(int i=1;i<=n;i++) str[i+n]=str[i];
13     
14     n*=2;
15     
16     for(register int i=1;i<=n;i++) u[str[i]]++;
17     for(register int i=1;i<=m;i++) u[i]+=u[i-1];
18     for(register int i=n;i>=1;i--) x[u[str[i]]--]=i;
19     r[x[1]]=1;
20     for(int i=2;i<=n;i++) r[x[i]]=r[x[i-1]]+(str[x[i]]!=str[x[i-1]]);
21     
22     for(int l=1;r[x[n]]<n;l<<=1) {
23         memset(u,0,sizeof u);
24         memset(v,0,sizeof v);
25         memcpy(o,r,sizeof r);
26         for(register int i=1;i<=n;i++) u[r[i]]++, v[r[i+l]]++;
27         for(register int i=1;i<=n;i++) u[i]+=u[i-1], v[i]+=v[i-1];
28         for(register int i=n;i>=1;i--) y[v[r[i+l]]--]=i;
29         for(register int i=n;i>=1;i--) x[u[r[y[i]]]--]=y[i];
30         r[x[1]]=1;
31         for(register int i=2;i<=n;i++)
32             r[x[i]]=r[x[i-1]]+((o[x[i]]!=o[x[i-1]])||(o[x[i]+l]!=(o[x[i-1]+l])));
33     }
34     
35     for(int i=1;i<=n;i++) 
36         if(x[i]<=n/2) {
37             for(register int j=1;j<=n/2;j++) printf("%d ",buf[str[x[i]+j-1]]);
38             return 0;
39         }
40 }

 

洛谷1368 工艺 - 后缀数组

标签:pre   body   using   sort   for   gis   bsp   scan   ace   

原文地址:https://www.cnblogs.com/mollnn/p/8449690.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!