佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物。生日礼物放在一个神奇的箱子中。箱子外边写了
一个长为n的字符串s,和m个问题。佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CE
O,嫁给高富帅,走上人生巅峰。每个问题均有a,b,c,d四个参数,问你子串s[a..b]的所有子串和s[c..d]的最长公
共前缀的长度的最大值是多少?佳媛姐姐并不擅长做这样的问题,所以她向你求助,你该如何帮助她呢?
标签:algorithm return 必须 pre nod 开箱 复杂 node range
对于每一次询问,输出答案。
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 const int N=100010;
6 int cnt[N],xx[N],yy[N],n;
7 char s[N];
8 int rank[N],sa[N],height[N],bin[20],f[N][18];
9 inline void get_sa(int m)
10 {
11 int *x=xx,*y=yy;
12 register int i,j,p,k;
13 for(i=0;i<m;++i)cnt[i]=0;
14 for(i=0;i<n;++i)++cnt[x[i]=s[i]];
15 for(i=1;i<m;++i)cnt[i]+=cnt[i-1];
16 for(i=n-1;~i;--i)sa[--cnt[x[i]]]=i;
17 for(k=1,p=0;k<=n&&p<n;k<<=1,m=p)
18 {
19 for(p=0,i=n-k;i<n;++i)y[p++]=i;
20 for(i=0;i<n;++i)if(sa[i]>=k)y[p++]=sa[i]-k;
21 for(i=0;i<m;++i)cnt[i]=0;
22 for(i=0;i<n;++i)++cnt[x[y[i]]];
23 for(i=1;i<m;++i)cnt[i]+=cnt[i-1];
24 for(i=n-1;~i;--i)sa[--cnt[x[y[i]]]]=y[i];
25 swap(x,y),x[sa[0]]=0,p=1;
26 for(i=1;i<n;++i)
27 x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?p-1:p++;
28 }
29 }
30 inline void get_height()
31 {
32 register int i,j,k;
33 for(i=0;i<n;++i)rank[sa[i]]=i;
34 for(k=i=0;i<n;height[rank[i++]]=k)
35 for(k=k?k-1:k,j=sa[rank[i]-1];s[i+k]==s[j+k];++k);
36 }
37 inline void ST()
38 {
39 register int i,j;
40 for(bin[0]=i=1;i<=18;++i)
41 bin[i]=bin[i-1]<<1;
42 for(j=0;j<n;++j)f[j][0]=height[j];
43 for(i=1;bin[i-1]<=n;++i)
44 for(j=0;j+bin[i]<=n;++j)
45 f[j][i]=min(f[j][i-1],f[j+bin[i-1]][i-1]);
46 }
47 struct node
48 {
49 node *ch[2];int cnt;
50 node(){ch[0]=ch[1]=NULL;cnt=0;}
51 inline void update(){cnt=ch[0]->cnt+ch[1]->cnt;}
52 }*null=new node(),*root[N];
53 inline node* newnode()
54 {node *o=new node();o->ch[1]=o->ch[0]=null;return o;}
55 inline bool query(node *a,node *b,int L,int R,int l,int r)
56 {
57 if(L<=l&&r<=R)return b->cnt-a->cnt;
58 int mi=l+r>>1;bool ret=0;
59 if(L<=mi)ret|=query(a->ch[0],b->ch[0],L,R,l,mi);
60 if(mi<R)ret|=query(a->ch[1],b->ch[1],L,R,mi+1,r);
61 return ret;
62 }
63 inline void get_range(int val,int &l,int &r)
64 {
65 register int j;
66 for(j=17;~j&&r<n;--j)
67 if(r+bin[j]-1<n&&f[r+1][j]>=val)r+=bin[j];
68 for(j=17;~j&&l;--j)
69 if(l-bin[j]+1>=0&&f[l-bin[j]+1][j]>=val)l-=bin[j];
70 }
71 inline bool judge(int a,int b,int c,int minimum)
72 {
73 int l=rank[c],r=rank[c],right=minimum?b-minimum+1:b;
74 get_range(minimum,l,r);
75 if(query(a?root[a-1]:null,root[right],l,r,0,n-1))return 1;
76 return 0;
77 }
78 inline void insert(node *&o,node *old,int l,int r,int pos)
79 {
80 o->cnt=old->cnt+1;int mi=(l+r)>>1;if(l==r)return;
81 if(pos<=mi)
82 o->ch[1]=old->ch[1],o->ch[0]=newnode(),
83 insert(o->ch[0],old->ch[0],l,mi,pos);
84 else
85 o->ch[0]=old->ch[0],o->ch[1]=newnode(),
86 insert(o->ch[1],old->ch[1],mi+1,r,pos);
87 o->update();
88 }
89 inline void Tree_intn()
90 {
91 register int i;
92 null->ch[0]=null->ch[1]=null;
93 for(i=0;i<n;++i)root[i]=newnode();
94 insert(root[0],null,0,n-1,rank[0]);
95 for(i=1;i<n;++i)
96 insert(root[i],root[i-1],0,n-1,rank[i]);
97 }
98 int main()
99 {
100 register int i,j,k,a,b,c,d,m,l,mi,r,ans;
101 scanf("%d%d%s",&n,&m,s),s[n++]=1,
102 get_sa(256),get_height(),ST(),Tree_intn();
103 while(m--)
104 {
105 scanf("%d%d%d%d",&a,&b,&c,&d),--a,--b,--c,--d;
106 l=0,mi,r=min(b-a+1,d-c+1),ans=0;
107 while(l<=r)
108 if(judge(a,b,c,(mi=l+r>>1)))l=mi+1,ans=mi;
109 else r=mi-1;
110 printf("%d\n",ans);
111 }
112 }
[BZOJ4556][Tjoi2016&Heoi2016]字符串 后缀数组+主席树
标签:algorithm return 必须 pre nod 开箱 复杂 node range
原文地址:http://www.cnblogs.com/LadyLex/p/7530903.html