poj3581 Sequence

2333

直接弃疗

第一遍搞出sa,去最小,注意sa>=3,(从1开始),后面直接输出,然后把前面剩下的复制,加到后面就好了,为什么这样呢?? %%% http://blog.163.com/just_gogo/blog/static/1914390652011823103842787/

还有,今天是找了一个神犇的后缀数组整理做的,感觉很爽(然后一天才4个题,感觉虚死了,代码能力什么的,,,没见过的样子)

后缀数组题目:http://blog.csdn.net/libin56842/article/details/46440923

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include<algorithm>
 5 #define N 100005
 6 #define inf 0x3f3f3f3f
 7 #define LL long long
 8 #define eps 1e-8
 9 using namespace std;
10 inline int ra()
11 {
12     int x=0,f=1; char ch=getchar();
13     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
14     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
15     return x*f;
16 }
17 
18 const int maxn=400005;
19 
20 int a[maxn],num[maxn],n,len,ans[maxn];
21 int sa[2][maxn],rank[2][maxn],v[maxn];
22 int p=0,q=1;
23 int find(int x)
24 {
25     int l=1,r=len-1;
26     while (l<=r)
27     {
28         int mid=l+r>>1;
29         if (num[mid]==x) return mid;
30         else if (num[mid]>x) r=mid-1;
31         else l=mid+1;
32     }
33 }
34 void cal_sa(int sa[maxn], int rank[maxn], int Sa[maxn], int Rank[maxn], int k)
35 {
36     for (int i=1; i<=n; i++) v[rank[sa[i]]]=i;
37     for (int i=n; i>=1; i--) if (sa[i]>k) Sa[v[rank[sa[i]-k]]--]=sa[i]-k;
38     for (int i=n-k+1; i<=n; i++) Sa[v[rank[i]]--]=i;
39     for (int i=1; i<=n; i++) Rank[Sa[i]]=Rank[Sa[i-1]]+(rank[Sa[i]]!=rank[Sa[i-1]] || rank[Sa[i]+k]!=rank[Sa[i-1]+k]);
40 }
41 void work()
42 {
43     for (int i=1; i<=n; i++) v[a[i]]++;
44     for (int i=1; i<=maxn-5; i++) v[i]+=v[i-1];
45     for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i;
46     for (int i=1; i<=n; i++) rank[p][sa[p][i]]=rank[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
47     for (int k=1; k<n; k<<=1,swap(p,q)) cal_sa(sa[p],rank[p],sa[q],rank[q],k);
48 }
49 void solve()
50 {
51     work(); int pos=0;
52     for (int i=1; i<=n; i++) 
53         if (sa[p][i]>=3)
54         {
55             pos=sa[p][i]-1;
56             for (int j=pos+1; j<=n; j++) printf("%d\n",ans[a[j]]);
57             break;
58         } // while (1);
59     for (int i=1; i<=pos; i++) a[i+pos]=a[i];
60     n=pos*2; memset(v,0,sizeof(v)); work();
61 //    for (int i=1; i<=n; i++) printf("%d ",sa[p][i]); cout<<endl;
62     for (int i=1; i<=n; i++) 
63         if (sa[p][i]>=2 && sa[p][i]<=pos)
64         {
65             pos=sa[p][i]-1; //cout<<"!!"<<pos<<"!!";
66             for (int j=pos+1; j<=n/2; j++) printf("%d\n",ans[a[j]]);
67             break;
68         }
69     for (int j=1; j<=pos; j++) printf("%d\n",ans[a[j]]);
70 }
71 int main(int argc, char const *argv[])
72 {
73     n=ra();
74     for (int i=n; i>=1; i--) a[i]=ra(),num[i]=a[i];
75     sort(num+1,num+n+1); 
76     len=unique(num+1,num+n+1)-num;
77     for (int i=1; i<=n; i++) ans[find(a[i])]=a[i],a[i]=find(a[i]);
78     solve();
79     return 0;
80 }

 

posted @ 2017-03-29 22:41  ws_ccd  阅读(195)  评论(0编辑  收藏  举报