Codeforces gym 100792B Banana Brain's Bracelet - z-box算法
2018-02-04 21:32
453 查看
传送门
我们可以求出翻转前的z数组z1以及翻转后的z数组z2,分别表示了C在每个位置可以匹配到的前缀和后缀
设C的长度为len,对于每个长度为i的前缀,我们对于长度>=len-i的后缀存一个set,然后在set中寻找距离他最远的满足要求的后缀的位置,这样就能找到关于这个前缀的最长B串
思路想起来很容易但是细节很多,容易推错(对于各种+1-1,实在想不明白可以通过举例子的方式来弄清楚)
代码:
题意:
给一个循环串A,和一个字符串C,求一个最长的A的子串B,使得将B首尾相接成一个循环串后,C是B的子串。Solution:
我们把A翻倍拼接,就可以消掉”A是循环串”z这个限制,发现C可以拆成一个前缀和一个后缀我们可以求出翻转前的z数组z1以及翻转后的z数组z2,分别表示了C在每个位置可以匹配到的前缀和后缀
设C的长度为len,对于每个长度为i的前缀,我们对于长度>=len-i的后缀存一个set,然后在set中寻找距离他最远的满足要求的后缀的位置,这样就能找到关于这个前缀的最长B串
思路想起来很容易但是细节很多,容易推错(对于各种+1-1,实在想不明白可以通过举例子的方式来弄清楚)
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<set> using namespace std; char a[500010],b[1500010]; int n,m,len,z1[1500010],z2[1500010]; int l,r; int ans=0; vector<int> ll[500010],rr[500010]; void getz(int z[]) { l=r=0; for (int i=1;i<=len;i++) { if (i>r) { int t=i,bg=0; while (b[t]==b[bg]) t++,bg++; z[i]=bg; r=t-1; l=i; } else { if (z[i-l]<r-i+1) z[i]=z[i-l]; else { int t=r+1,bg=r-i+1; while (b[t]==b[bg]) t++,bg++; z[i]=bg; r=t-1; l=i; } } } } int main() { ans=-1; scanf("%s",a);scanf("%s",b); n=strlen(a);m=strlen(b); b[m]='$'; for (int i=0;i<n;i++) b[m+i+1]=a[i]; for (int i=0;i<n-1;i++) b[m+n+i+1]=a[i]; len=n+n+m; getz(z1); for (int i=0,j=m-1;i<j;i++,j--) swap(b[i],b[j]); for (int i=m+1,j=len-1;i<j;i++,j--) swap(b[i],b[j]); getz(z2); for (int i=m+1;i<len;i++) { ll[z1[i]].push_back(i-m-1); rr[z2[i]].push_back(len-i-1); } set<int> seq; for (int i=0 d151 ;i<=m;i++) { for (int j=0;j<rr[m-i].size();j++) seq.insert(rr[m-i][j]); for (int j=0;j<ll[i].size();j++) { set<int>::iterator it=seq.lower_bound(ll[i][j]-n+m-1); if (it!=seq.end()&&*it<ll[i][j]) ans=max(ans,ll[i][j]-*it-1+m); } } printf("%d",ans); }
相关文章推荐
- codeforces GYM 100971F 公式题或者三分
- Codeforces gym 100971 D. Laying Cables 单调栈
- CodeForces Gym 100989E Accepted Passwords
- Codeforces Gym - 101635K Blowing Candles [旋转卡壳]
- CodeForces Gym 100646G The Worm Turns DFS
- Codeforces Gym 100531D Digits (暴力、打表)
- UVA Live 6129 (Codeforces Gym 100642H) Sofa, So Good 最小费用流
- 【Codeforces Gym - 100187J】 + DFS
- [三分套三分] Codeforces Gym 100307 NEERC 13 E. Easy Geometry
- Codeforces Gym 100231F Solitaire 折半搜索
- Codeforces gym 101149 G 想法
- Codeforces Gym 100650B Countdown DFS
- 【模拟】NEERC15 A Adjustment Office (Codeforces GYM 100851)
- 【模拟】NEERC15 G Generators(2015-2016 ACM-ICPC)(Codeforces GYM 100851)
- Codeforces GYM 100548 I - International Collegiate Routing Contest 2014 ACM Xian Regional Contest
- Codeforces Gym 100187K K. Perpetuum Mobile 构造
- 【宽搜】ECNA 2015 D Rings (Codeforces GYM 100825)
- Codeforces Gym 221682 W Grid Coloring(DP)
- Codeforces Gym 100570 E. Palindrome Query Manacher
- Codeforces Gym 100286I iSharp 水题