码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ4556 HEOI2016 字符串

时间:2018-01-06 23:18:14      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:can   lib   scan   names   复杂   str   const   har   cst   

后缀数组。

复习了后缀数组后发现这题真的很好写。

我们只需要将c依次向前向后扩展,找落在[a,b]区间内的最大值,遍历过程中不断用height数组更新。

复杂度就是后缀数组,比主席树的快多了。

By:大奕哥

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cstdio>
 6 using namespace std;
 7 const int N=1e5+10;
 8 inline int read()
 9 {
10     char ch;ch=getchar();int x=0;
11     while(ch<0||ch>9)ch=getchar();
12     while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar();
13     return x;
14 }
15 int wv[N],wu[N],wa[N],wb[N],sa[N],rank[N],height[N],r[N];
16 inline int cmp(int *r,int a,int b,int l)
17 {
18     return r[a]==r[b]&&r[a+l]==r[b+l];
19 }
20 void da(int *r,int *sa,int n,int m)
21 {
22     int i,j,p;int *x=wa,*y=wb;
23     for(i=0;i<m;++i)wu[i]=0;
24     for(i=0;i<n;++i)wu[x[i]=r[i]]++;
25     for(i=1;i<m;++i)wu[i]+=wu[i-1];
26     for(i=n-1;i>=0;--i)sa[--wu[x[i]]]=i;
27     for(j=1,p=1;p<n;j<<=1,m=p)
28     {
29         for(p=0,i=n-j;i<n;++i)y[p++]=i;
30         for(i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
31         for(i=0;i<n;++i)wv[i]=x[y[i]];
32         for(i=0;i<m;++i)wu[i]=0;
33         for(i=0;i<n;++i)wu[wv[i]]++;
34         for(i=1;i<m;++i)wu[i]+=wu[i-1];
35         for(i=n-1;i>=0;--i)sa[--wu[wv[i]]]=y[i];
36         for(swap(x,y),p=1,x[sa[0]]=0,i=1;i<n;++i)
37         x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
38     }
39     return;
40 }
41 void calcHeight(int *rank,int *sa,int n)
42 {
43     int i,j,k=0;
44     for(i=1;i<=n;++i)rank[sa[i]]=i;
45     for(i=0;i<n;height[rank[i++]]=k)
46         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];++k);
47     return;
48 }
49 char s[N];
50 void work(int a,int b,int c,int d,int n)
51 {
52     int len=0,tmp=N;
53     if(c>=a&&c<=b)len=max(len,min(d-c+1,b-c+1));
54     for(int i=rank[c-1];i>=2;--i)
55     {
56         tmp=min(tmp,height[i]);
57         if(height[i]==0||tmp<=len)break;
58         if(sa[i-1]>=a-1&&sa[i-1]<=b-1)
59         {
60             len=max(len,min(min(min(tmp,height[i]),b-sa[i-1]),d-c+1));
61         }
62     }
63     tmp=N;
64     for(int i=rank[c-1]+1;i<=n;++i)
65     {
66         tmp=min(tmp,height[i]);
67         if(height[i]==0||tmp<=len)break;
68         if(sa[i]>=a-1&&sa[i]<=b-1)
69         {
70             len=max(len,min(min(min(tmp,height[i]),b-sa[i]),d-c+1));
71         }
72     }
73     printf("%d\n",len);
74 }
75 int main()
76 {
77     int n,m,a,b,c,d;
78     n=read();m=read();
79     scanf("%s",s);
80     int len=strlen(s);
81     for(int i=0;i<len;++i)r[i]=s[i];r[len]=0;
82     da(r,sa,len+1,216);calcHeight(rank,sa,len);
83     for(int i=1;i<=m;++i)
84     {
85         a=read();b=read();c=read();d=read();
86         work(a,b,c,d,len);
87     }
88     return 0;
89 }

 

BZOJ4556 HEOI2016 字符串

标签:can   lib   scan   names   复杂   str   const   har   cst   

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8215412.html

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