bzoj 3230 相似子串 后缀数组
来源:互联网 发布:迅捷网络登录密码多少 编辑:程序博客网 时间:2024/06/05 04:42
直接对正串反串建后缀数组,然后求一个h和h的rmq。对于正串处理一个(n-sa[i]+1)-h[i]的前缀和。
然后对于给的第i个子串,直接在前缀和上二分。然后rmq。
注意long long
#include <bits/stdc++.h>using namespace std;#define A 27#define N 110000#define ll long long#define PA pair<int,int>int n,Q;int bir[N];ll v[N];struct SA{ char s[N]; int sa[N],h[N][21],rank[N],tr[N],has[N]; int cmp(int x,int y,int k) { if(x+k>n||y+k>n)return 0; return rank[x]==rank[y]&&rank[x+k]==rank[y+k]; } void getsa() { int i,cnt; for(i=1;i<=n;i++)has[s[i]-'a'+1]++; for(i=1,cnt=0;i<=A;i++)if(has[i])tr[i]=++cnt; for(i=1;i<=A;i++)has[i]+=has[i-1]; for(i=1;i<=n;i++)rank[i]=tr[s[i]-'a'+1],sa[has[s[i]-'a'+1]--]=i; for(int k=1;cnt!=n;k<<=1) { for(i=1;i<=n;i++)has[i]=0; for(i=1;i<=n;i++)has[rank[i]]++; for(i=1;i<=n;i++)has[i]+=has[i-1]; for(i=n;i>=1;i--)if(sa[i]>k)tr[sa[i]-k]=has[rank[sa[i]-k]]--; for(i=1;i<=k;i++)tr[n-i+1]=has[rank[n-i+1]]--; for(i=1;i<=n;i++)sa[tr[i]]=i; for(i=1,cnt=0;i<=n;i++)tr[sa[i]]=cmp(sa[i],sa[i-1],k) ? cnt:++cnt; for(i=1;i<=n;i++)rank[i]=tr[i]; } for(i=1;i<=n;i++) { if(rank[i]==1)continue; for(int j=max(h[rank[i-1]][0]-1,1);;j++) { if(s[i+j-1]==s[sa[rank[i]-1]+j-1])h[rank[i]][0]=j; else break; } } for(i=1;i<=20;i++) for(int j=1;j<=n;j++) if(j>1<<i)h[j][i]=min(h[j][i-1],h[j-(1<<i-1)][i-1]); } void getv() { for(int i=1;i<=n;i++) v[i]=v[i-1]+(n-sa[i]+1)-h[i][0]; } PA find(ll x) { if(x>v[n])return make_pair(-1,-1); int t=lower_bound(v+1,v+1+n,x)-v; return make_pair(t,(n-sa[t]+1)-(v[t]-x)); } int rmq(int x,int y) { if(x==y)return n; if(x>y)swap(x,y); int t=bir[y-x]; return min(h[y][t],h[x+(1<<t)][t]); }}a1,a2;int trs(PA x){ int t=a1.sa[x.first]+x.second-1; return a2.rank[n-t+1];} int main(){ //freopen("tt.in","r",stdin); scanf("%d%d",&n,&Q); scanf("%s",a1.s+1); a1.getsa();a1.getv(); for(int i=n;i>=1;i--)a2.s[n-i+1]=a1.s[i]; a2.getsa(); for(int i=1,j=0;i<=n;i++) { if((1<<j+1)==i)j++; bir[i]=j; } for(ll x,y;Q--;) { scanf("%lld%lld",&x,&y); PA r1=a1.find(x),r2=a1.find(y); if(r1.first==-1||r2.first==-1) {puts("-1");continue;} int t1=a1.rmq(r1.first,r2.first); t1=min(t1,r1.second); t1=min(t1,r2.second); int t2=a2.rmq(trs(r1),trs(r2)); t2=min(t2,r1.second); t2=min(t2,r2.second); printf("%lld\n",(ll)t1*t1+(ll)t2*t2); } return 0;}
0 0
- BZOJ 3230 相似子串 后缀数组
- bzoj 3230 相似子串 后缀数组
- 【BZOJ 3230】相似子串 后缀数组
- BZOJ 3230 相似子串|后缀数组|RMQ
- bzoj 3230: 相似子串 (后缀数组+RMQ+二分)
- BZOJ 3230 相似子串 后缀数组+二分+ST表
- bzoj 3230: 相似子串 后缀数组+rmq+二分
- bzoj 3230 相似子串
- [BZOJ3230]相似子串(后缀数组+二分+st表)
- bzoj3230: 相似子串(后缀数组+ST表)
- BZOJ3230 相似子串 后缀自动机做法
- BZOJ 3230 后缀数组+ST
- 后缀子串排序(后缀数组)
- 后缀数组--重复子串
- BZOJ 2946 [Poi2000]公共串 后缀数组
- 【BZOJ 2946】[Poi2000]公共串 后缀数组
- BZOJ 2946: [Poi2000]公共串 后缀数组
- 【bzoj 1692】后缀数组
- 英文专业名词收集
- intent传数据和EventBus各自用处
- web开发性能优化---UI界面篇
- Android 生命周期的注意点
- android 全屏去掉状态栏和横竖屏设定
- bzoj 3230 相似子串 后缀数组
- 解读Tapestry5.1——页面渲染
- html5的data-*属性
- 算法-第四版-练习1.3.30解答
- 2.java设计模式接口型模式(读书笔记)(讲解接口和抽象类)
- ES6新特性:使用export和import实现模块化
- Android设置过头像后怎么保存啊,求助
- 预估未来必不可少的5个IT技能
- PHP的strtotime计算2038年以上日期的时间戳错误